Bearsampp 2026.9.23
Loading...
Searching...
No Matches
class.bin.mariadb.php
Go to the documentation of this file.
1<?php
2/*
3 * Copyright (c) 2021-2026 Bearsampp
4 * License: GNU General Public License version 3 or later; see LICENSE.txt
5 * Author: Bear
6 * Website: https://bearsampp.com
7 * Github: https://github.com/Bearsampp
8 */
9
16class BinMariadb extends Module
17{
21 const SERVICE_NAME = 'bearsamppmariadb';
22
26 const ROOT_CFG_ENABLE = 'mariadbEnable';
30 const ROOT_CFG_VERSION = 'mariadbVersion';
31
35 const LOCAL_CFG_EXE = 'mariadbExe';
39 const LOCAL_CFG_CLI_EXE = 'mariadbCliExe';
43 const LOCAL_CFG_ADMIN = 'mariadbAdmin';
47 const LOCAL_CFG_CONF = 'mariadbConf';
51 const LOCAL_CFG_PORT = 'mariadbPort';
55 const LOCAL_CFG_ROOT_USER = 'mariadbRootUser';
59 const LOCAL_CFG_ROOT_PWD = 'mariadbRootPwd';
60
64 const CMD_VERSION = '--version';
68 const CMD_VARIABLES = 'variables';
72 const CMD_SYNTAX_CHECK = '--help --verbose 1>NUL';
73
77 private $service;
81 private $errorLog;
82
86 private $exe;
90 private $conf;
94 private $port;
98 private $rootUser;
102 private $rootPwd;
106 private $cliExe;
110 private $admin;
111
118 public function __construct($id, $type)
119 {
120 Log::initClass($this);
121 $this->reload($id, $type);
122 }
123
130 public function reload($id = null, $type = null)
131 {
133 Log::reloadClass($this);
134
135 $this->name = $bearsamppLang->getValue(Lang::MARIADB);
136 $this->version = $bearsamppConfig->getRaw(self::ROOT_CFG_VERSION);
137 parent::reload($id, $type);
138
139 $this->enable = $this->enable && $bearsamppConfig->getRaw(self::ROOT_CFG_ENABLE);
140 $this->service = new Win32Service(self::SERVICE_NAME);
141 $this->errorLog = Path::getLogsPath() . '/mariadb.log';
142
143 if ($this->bearsamppConfRaw !== false) {
144 $this->exe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_EXE];
145 $this->conf = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CONF];
146 $this->port = $this->bearsamppConfRaw[self::LOCAL_CFG_PORT];
147 $this->rootUser = isset($this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_USER]) ? $this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_USER] : 'root';
148 $this->rootPwd = isset($this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_PWD]) ? $this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_PWD] : '';
149 $this->cliExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CLI_EXE];
150 $this->admin = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_ADMIN];
151 }
152
153 if (!$this->enable) {
154 Log::info($this->name . ' is not enabled!');
155
156 return;
157 }
158 if (!is_dir($this->currentPath)) {
159 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->currentPath));
160
161 return;
162 }
163 if (!is_dir($this->symlinkPath)) {
164 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->symlinkPath));
165
166 return;
167 }
168 if (!is_file($this->bearsamppConf)) {
169 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->bearsamppConf));
170
171 return;
172 }
173 if (!is_file($this->exe)) {
174 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->exe));
175
176 return;
177 }
178 if (!is_file($this->conf)) {
179 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->conf));
180
181 return;
182 }
183 if (!is_numeric($this->port) || $this->port <= 0) {
184 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_PORT, $this->port));
185
186 return;
187 }
188 if (empty($this->rootUser)) {
189 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_ROOT_USER, $this->rootUser));
190
191 return;
192 }
193 if (!is_file($this->cliExe)) {
194 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->cliExe));
195
196 return;
197 }
198 if (!is_file($this->admin)) {
199 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->admin));
200
201 return;
202 }
203
204 $this->service->setDisplayName(APP_TITLE . ' ' . $this->getName());
205 $this->service->setBinPath($this->exe);
206 $this->service->setParams('--defaults-file="' . Path::formatWindowsPath($this->conf) . '" ' . self::SERVICE_NAME);
207 $this->service->setStartType(Win32Service::SERVICE_DEMAND_START);
208 $this->service->setErrorControl(Win32Service::SERVER_ERROR_NORMAL);
209 }
210
216 protected function replaceAll($params)
217 {
218 $content = file_get_contents($this->bearsamppConf);
219
220 foreach ($params as $key => $value) {
221 $content = preg_replace('|' . $key . ' = .*|', $key . ' = ' . '"' . $value . '"', $content);
222 $this->bearsamppConfRaw[$key] = $value;
223 switch ($key) {
224 case self::LOCAL_CFG_PORT:
225 $this->port = $value;
226 break;
227 case self::LOCAL_CFG_ROOT_USER:
228 $this->rootUser = $value;
229 break;
230 case self::LOCAL_CFG_ROOT_PWD:
231 $this->rootPwd = $value;
232 break;
233 }
234 }
235
236 file_put_contents($this->bearsamppConf, $content);
237
238 self::invalidateConfigCacheForPath($this->bearsamppConf);
239 }
240
250 public function changePort($port, $checkUsed = false, $wbProgressBar = null)
251 {
252 global $bearsamppWinbinder;
253
254 if (!Util::isValidPort($port)) {
255 Log::error($this->getName() . ' port not valid: ' . $port);
256
257 return false;
258 }
259
260 $port = intval($port);
261 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
262
263 $isPortInUse = ServiceHelper::isPortInUse($port);
264 if (!$checkUsed || $isPortInUse === false) {
265 // bearsampp.conf
266 $this->setPort($port);
267 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
268
269 // conf
270 $this->update();
271 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
272
273 return true;
274 }
275
276 Log::debug($this->getName() . ' port in used: ' . $port . ' - ' . $isPortInUse);
277
278 return $isPortInUse;
279 }
280
289 public function checkPort($port, $showWindow = false)
290 {
291 global $bearsamppLang, $bearsamppWinbinder;
292 $boxTitle = sprintf($bearsamppLang->getValue(Lang::CHECK_PORT_TITLE), $this->getName(), $port);
293
294 if (!Util::isValidPort($port)) {
295 Log::error($this->getName() . ' port not valid: ' . $port);
296
297 return false;
298 }
299
300 $fp = @fsockopen(APP_LOCALHOST, $port, $errno, $errstr, 5);
301 if ($fp) {
302 // Reset mysqli to non-exception mode so connect/query failures
303 // return false instead of throwing an uncaught mysqli_sql_exception
304 // that would freeze the WinBinder GUI thread.
305 mysqli_report(MYSQLI_REPORT_OFF);
306
307 $dbLink = mysqli_connect(APP_LOCALHOST . ':' . $port, $this->rootUser, $this->rootPwd);
308 $isMariadb = false;
309 $version = false;
310
311 if ($dbLink) {
312 $result = mysqli_query($dbLink, 'SHOW VARIABLES');
313 if ($result) {
314 while (false !== ($row = mysqli_fetch_array($result, MYSQLI_NUM))) {
315 if ($row[0] == 'version') {
316 $version = explode('-', $row[1]);
317 $version = count($version) > 1 ? $version[0] : $row[1];
318 }
319 if ($row[0] == 'version_comment' && UtilString::startWith(strtolower($row[1]), 'mariadb')) {
320 $isMariadb = true;
321 }
322 if ($isMariadb && $version !== false) {
323 break;
324 }
325 }
326 if (!$isMariadb) {
327 Log::debug($this->getName() . ' port used by another DBMS: ' . $port);
328 if ($showWindow) {
329 $bearsamppWinbinder->messageBoxWarning(
331 $boxTitle
332 );
333 }
334 } else {
335 Log::debug($this->getName() . ' port ' . $port . ' is used by: ' . $this->getName() . ' ' . $version);
336 if ($showWindow) {
337 $bearsamppWinbinder->messageBoxInfo(
338 sprintf($bearsamppLang->getValue(Lang::PORT_USED_BY), $port, $this->getName() . ' ' . $version),
339 $boxTitle
340 );
341 }
342
343 return true;
344 }
345 }
346 mysqli_close($dbLink);
347 } else {
348 Log::debug($this->getName() . ' port ' . $port . ' is used by another application');
349 if ($showWindow) {
350 $bearsamppWinbinder->messageBoxWarning(
351 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED_BY), $port),
352 $boxTitle
353 );
354 }
355 }
356 } else {
357 Log::debug($this->getName() . ' port ' . $port . ' is not used');
358 if ($showWindow) {
359 $bearsamppWinbinder->messageBoxError(
360 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED), $port),
361 $boxTitle
362 );
363 }
364 }
365
366 return false;
367 }
368
378 public function changeRootPassword($currentPwd, $newPwd, $wbProgressBar = null)
379 {
380 global $bearsamppWinbinder;
381
382 $error = null;
383 $dbLink = false;
384
385 try {
386 // Connect
387 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
388
389 // Since PHP 8.1 mysqli defaults to exception mode (MYSQLI_REPORT_STRICT),
390 // so a failed auth throws mysqli_sql_exception instead of returning false.
391 // Reset to OFF so calls return false and mysqli_connect_error() is set,
392 // keeping the documented bool|string contract and avoiding an uncaught
393 // exception that would freeze the WinBinder GUI thread.
394 mysqli_report(MYSQLI_REPORT_OFF);
395
396 $dbLink = mysqli_init();
397 mysqli_options($dbLink, MYSQLI_OPT_CONNECT_TIMEOUT, 5);
398 if (!mysqli_real_connect($dbLink, APP_LOCALHOST, $this->rootUser, $currentPwd, null, $this->port)) {
399 throw new \RuntimeException(mysqli_connect_error());
400 }
401
402 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
403
404 // Bound metadata-lock/table-lock waits so a password change can
405 // never freeze the UI: any lock contention times out in seconds
406 // instead of waiting for the server's default (often very large)
407 // lock_wait_timeout.
408 mysqli_query($dbLink, 'SET SESSION lock_wait_timeout = 5');
409 mysqli_query($dbLink, 'SET SESSION innodb_lock_wait_timeout = 5');
410
411 // ALTER USER works reliably across MariaDB 10.3+ and avoids
412 // known SET PASSWORD bugs (MDEV-16774, MDEV-17136) and
413 // metadata lock contention on the mysql.user table in 10.3.
414 // The user and host are given explicitly (not CURRENT_USER()).
415 // The password is escaped so an empty (blank) password is
416 // allowed: IDENTIFIED BY '' sets a blank password.
417 $escapedUser = mysqli_real_escape_string($dbLink, $this->rootUser);
418 $escapedPwd = mysqli_real_escape_string($dbLink, $newPwd);
419 $sql = "ALTER USER '" . $escapedUser . "'@'localhost' IDENTIFIED BY '" . $escapedPwd . "'";
420
421 if (mysqli_query($dbLink, $sql) === false) {
422 throw new \RuntimeException(mysqli_error($dbLink));
423 }
424
425 // Preserve the existing progress-step count.
426 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
427 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
428
429 mysqli_close($dbLink);
430 $dbLink = false;
431
432 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
433 } catch (\Throwable $e) {
434 $error = $e->getMessage();
435
436 if ($dbLink) {
437 @mysqli_close($dbLink);
438 }
439 }
440
441 if (!empty($error)) {
442 return $error;
443 }
444
445 // bearsampp.conf
446 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
447 $this->setRootPwd($newPwd);
448
449 // conf
450 $this->update();
451 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
452
453 return true;
454 }
455
464 public function checkRootPassword($currentPwd = null, $wbProgressBar = null)
465 {
466 global $bearsamppWinbinder;
467 $currentPwd = $currentPwd == null ? $this->rootPwd : $currentPwd;
468 $error = null;
469
470 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
471
472 // Reset mysqli to non-exception mode so a bad password returns false
473 // (with mysqli_connect_error() set) instead of throwing an uncaught
474 // mysqli_sql_exception that would freeze the WinBinder GUI thread.
475 mysqli_report(MYSQLI_REPORT_OFF);
476
477 $dbLink = mysqli_init();
478 mysqli_options($dbLink, MYSQLI_OPT_CONNECT_TIMEOUT, 5);
479 if (!mysqli_real_connect($dbLink, APP_LOCALHOST, $this->rootUser, $currentPwd, null, $this->port)) {
480 $error = mysqli_connect_error();
481 }
482
483 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
484 if ($dbLink) {
485 mysqli_close($dbLink);
486 }
487
488 if (!empty($error)) {
489 return $error;
490 }
491
492 return true;
493 }
494
503 public function switchVersion($version, $showWindow = false)
504 {
505 Log::debug('Switch ' . $this->name . ' version to ' . $version);
506
507 return $this->updateConfig($version, 0, $showWindow);
508 }
509
519 protected function updateConfig($version = null, $sub = 0, $showWindow = false)
520 {
521 global $bearsamppLang, $bearsamppApps, $bearsamppWinbinder;
522
523 if (!$this->enable) {
524 return true;
525 }
526
527 $version = $version == null ? $this->version : $version;
528 Log::debug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'Update ' . $this->name . ' ' . $version . ' config');
529
530 $boxTitle = sprintf($bearsamppLang->getValue(Lang::SWITCH_VERSION_TITLE), $this->getName(), $version);
531
532 $conf = str_replace('mariadb' . $this->getVersion(), 'mariadb' . $version, $this->getConf());
533 $bearsamppConf = str_replace('mariadb' . $this->getVersion(), 'mariadb' . $version, $this->bearsamppConf);
534
535 if (!file_exists($conf) || !file_exists($bearsamppConf)) {
536 Log::error('bearsampp config files not found for ' . $this->getName() . ' ' . $version);
537 if ($showWindow) {
538 $bearsamppWinbinder->messageBoxError(
539 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_NOT_FOUND_ERROR), $this->getName() . ' ' . $version),
540 $boxTitle
541 );
542 }
543
544 return false;
545 }
546
547 $bearsamppConfRaw = parse_ini_file($bearsamppConf);
548 if ($bearsamppConfRaw === false || !isset($bearsamppConfRaw[self::ROOT_CFG_VERSION]) || $bearsamppConfRaw[self::ROOT_CFG_VERSION] != $version) {
549 Log::error('bearsampp config file malformed for ' . $this->getName() . ' ' . $version);
550 if ($showWindow) {
551 $bearsamppWinbinder->messageBoxError(
552 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_MALFORMED_ERROR), $this->getName() . ' ' . $version),
553 $boxTitle
554 );
555 }
556
557 return false;
558 }
559
560 // bearsampp.conf
561 $this->setVersion($version);
562
563 // conf
564 Util::replaceInFile($this->getConf(), array(
565 '/^port(.*?)=(.*?)(\d+)/' => 'port = ' . $this->port
566 ));
567
568 // phpmyadmin
569 $bearsamppApps->getPhpmyadmin()->update($sub + 1);
570
571 return true;
572 }
573
583 public function getCmdLineOutput($cmd)
584 {
585 $result = array(
586 'syntaxOk' => false,
587 'content' => null,
588 );
589
590 $bin = $this->getExe();
591 $removeLines = 0;
592 $outputFrom = '';
593 if ($cmd == self::CMD_SYNTAX_CHECK) {
594 $outputFrom = '2';
595 } elseif ($cmd == self::CMD_VARIABLES) {
596 $bin = $this->getAdmin();
597 $cmd .= ' --user=' . $this->getRootUser();
598 if ($this->getRootPwd()) {
599 $cmd .= ' --password=' . $this->getRootPwd();
600 }
601 $removeLines = 2;
602 }
603
604 if (file_exists($bin)) {
605 $tmpResult = Batch::exec('mariadbGetCmdLineOutput', '"' . $bin . '" ' . $cmd . ' ' . $outputFrom, 5);
606 if ($tmpResult !== false && is_array($tmpResult)) {
607 $result['syntaxOk'] = empty($tmpResult) || !UtilString::contains(trim($tmpResult[count($tmpResult) - 1]), '[ERROR]');
608 for ($i = 0; $i < $removeLines; $i++) {
609 unset($tmpResult[$i]);
610 }
611 $result['content'] = trim(str_replace($bin, '', implode(PHP_EOL, $tmpResult)));
612 }
613 }
614
615 return $result;
616 }
617
623 public function setVersion($version)
624 {
625 global $bearsamppConfig;
626 $this->version = $version;
627 $bearsamppConfig->replace(self::ROOT_CFG_VERSION, $version);
628 $this->reload();
629 }
630
636 public function getService()
637 {
638 return $this->service;
639 }
640
647 public function setEnable($enabled, $showWindow = false)
648 {
649 global $bearsamppConfig, $bearsamppLang, $bearsamppWinbinder;
650
651 if ($enabled == Config::ENABLED && !is_dir($this->currentPath)) {
652 Log::debug($this->getName() . ' cannot be enabled because bundle ' . $this->getVersion() . ' does not exist in ' . $this->currentPath);
653 if ($showWindow) {
654 $bearsamppWinbinder->messageBoxError(
655 sprintf($bearsamppLang->getValue(Lang::ENABLE_BUNDLE_NOT_EXIST), $this->getName(), $this->getVersion(), $this->currentPath),
656 sprintf($bearsamppLang->getValue(Lang::ENABLE_TITLE), $this->getName())
657 );
658 }
659 $enabled = Config::DISABLED;
660 }
661
662 Log::info($this->getName() . ' switched to ' . ($enabled == Config::ENABLED ? 'enabled' : 'disabled'));
663 $this->enable = $enabled == Config::ENABLED;
664 $bearsamppConfig->replace(self::ROOT_CFG_ENABLE, $enabled);
665
666 $this->reload();
667 if ($this->enable) {
668 ServiceHelper::installService($this, $this->port, self::CMD_SYNTAX_CHECK, $showWindow);
669 } else {
670 ServiceHelper::removeService($this->service, $this->name);
671 }
672 }
673
679 public function getErrorLog()
680 {
681 return $this->errorLog;
682 }
683
689 public function getExe()
690 {
691 return $this->exe;
692 }
693
699 public function getConf()
700 {
701 return $this->conf;
702 }
703
709 public function getPort()
710 {
711 return $this->port;
712 }
713
719 public function setPort($port)
720 {
721 $this->replace(self::LOCAL_CFG_PORT, $port);
722 }
723
729 public function getRootUser()
730 {
731 return $this->rootUser;
732 }
733
739 public function setRootUser($rootUser)
740 {
741 $this->replace(self::LOCAL_CFG_ROOT_USER, $rootUser);
742 }
743
749 public function getRootPwd()
750 {
751 return $this->rootPwd;
752 }
753
759 public function setRootPwd($rootPwd)
760 {
761 $this->replace(self::LOCAL_CFG_ROOT_PWD, $rootPwd);
762 }
763
769 public function getCliExe()
770 {
771 return $this->cliExe;
772 }
773
779 public function getAdmin()
780 {
781 return $this->admin;
782 }
783
789 public function getDataDir()
790 {
791 return $this->currentPath . '/data';
792 }
793
802 public function initData($path = null, $version = null)
803 {
804 Log::trace('Starting MariaDB data initialization');
805 $startTime = microtime(true);
806
807 $path = $path != null ? $path : Path::getModuleCurrentPath($this);
808 $version = $version != null ? $version : $this->getVersion();
809 $dataDir = $path . '/data';
810
811 if (is_dir($dataDir . '/mysql')) {
812 Log::trace('MariaDB data directory already initialized');
813
814 return true;
815 }
816
817 if (!is_dir($dataDir)) {
818 @mkdir($dataDir, 0777, true);
819 Log::trace('Created MariaDB data directory');
820 }
821
822 // Check for init.bat first
823 if (file_exists($path . '/init.bat')) {
824 Log::trace('Initializing MariaDB via init.bat');
825 try {
827 } catch (\Throwable $e) {
828 Log::trace('Error during MariaDB initialization via Batch: ' . $e->getMessage());
829
830 return false;
831 }
832 } else {
833 // Use mariadb-install-db.exe
834 Log::trace('Initializing MariaDB via mariadb-install-db.exe');
835 $installDbExe = $path . '/bin/mariadb-install-db.exe';
836 if (!file_exists($installDbExe)) {
837 $installDbExe = $path . '/bin/mysql_install_db.exe';
838 }
839
840 if (file_exists($installDbExe)) {
841 $cmd = '"' . Path::formatWindowsPath($installDbExe) . '"';
842 $cmd .= ' --datadir="' . Path::formatWindowsPath($dataDir) . '"';
843
844 try {
845 Batch::exec('initializeMariadb', $cmd, 60);
846 } catch (\Throwable $e) {
847 Log::trace('Error during MariaDB initialization via mariadb-install-db: ' . $e->getMessage());
848
849 return false;
850 }
851 } else {
852 Log::error('MariaDB initialization failed: No init.bat or mariadb-install-db.exe found');
853
854 return false;
855 }
856 }
857
858 // Verify initialization
859 if (!is_dir($dataDir . '/mysql')) {
860 Log::trace('MariaDB initialization appears to have failed: mysql directory still missing');
861
862 return false;
863 }
864
865 $totalTime = round(microtime(true) - $startTime, 2);
866 Log::trace("MariaDB initialization completed in {$totalTime}s");
867
868 return true;
869 }
870}
$result
global $bearsamppLang
global $bearsamppRoot
static initializeMariadb($path)
static exec($basename, $content, $timeout=true, $catchOutput=true, $standalone=false, $silent=true, $rebuild=true)
updateConfig($version=null, $sub=0, $showWindow=false)
const LOCAL_CFG_ROOT_USER
setRootUser($rootUser)
changeRootPassword($currentPwd, $newPwd, $wbProgressBar=null)
switchVersion($version, $showWindow=false)
setVersion($version)
checkPort($port, $showWindow=false)
changePort($port, $checkUsed=false, $wbProgressBar=null)
setEnable($enabled, $showWindow=false)
initData($path=null, $version=null)
reload($id=null, $type=null)
__construct($id, $type)
checkRootPassword($currentPwd=null, $wbProgressBar=null)
setRootPwd($rootPwd)
const DISABLED
const ENABLED
const MARIADB
const ENABLE_BUNDLE_NOT_EXIST
const BEARSAMPP_CONF_MALFORMED_ERROR
const ERROR_EXE_NOT_FOUND
const ERROR_CONF_NOT_FOUND
const BEARSAMPP_CONF_NOT_FOUND_ERROR
const PORT_NOT_USED
const ERROR_INVALID_PARAMETER
const ENABLE_TITLE
const PORT_NOT_USED_BY
const SWITCH_VERSION_TITLE
const CHECK_PORT_TITLE
const PORT_USED_BY
const PORT_USED_BY_ANOTHER_DBMS
const ERROR_FILE_NOT_FOUND
static info($data, $file=null)
static debug($data, $file=null)
static reloadClass($classInstance)
static trace($data, $file=null)
static error($data, $file=null)
static initClass($classInstance)
update($sub=0, $showWindow=false)
static invalidateConfigCacheForPath($sourcePath)
replace($key, $value)
static getLogsPath($aetrayPath=false)
static formatWindowsPath($path)
static getModuleCurrentPath($module)
static installService($bin, $port, $syntaxCheckCmd, $showWindow=false)
static removeService($service, $name)
static isPortInUse($port)
static isValidPort($port)
static replaceInFile($path, $replaceList)
static contains($string, $search)
static startWith($string, $search)
global $bearsamppConfig
Definition homepage.php:46
const APP_LOCALHOST
Definition root.php:21
const APP_TITLE
Definition root.php:19