Bearsampp 2026.9.23
Loading...
Searching...
No Matches
class.bin.mysql.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 BinMysql extends Module
17{
21 const SERVICE_NAME = 'bearsamppmysql';
22
26 const ROOT_CFG_ENABLE = 'mysqlEnable';
30 const ROOT_CFG_VERSION = 'mysqlVersion';
31
35 const LOCAL_CFG_EXE = 'mysqlExe';
39 const LOCAL_CFG_CLI_EXE = 'mysqlCliExe';
43 const LOCAL_CFG_ADMIN = 'mysqlAdmin';
47 const LOCAL_CFG_CONF = 'mysqlConf';
51 const LOCAL_CFG_PORT = 'mysqlPort';
55 const LOCAL_CFG_ROOT_USER = 'mysqlRootUser';
59 const LOCAL_CFG_ROOT_PWD = 'mysqlRootPwd';
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;
114 private $dataDir;
115
122 public function __construct($id, $type)
123 {
124 Log::initClass($this);
125 $this->reload($id, $type);
126 }
127
134 public function reload($id = null, $type = null)
135 {
137 Log::reloadClass($this);
138
139 $this->name = $bearsamppLang->getValue(Lang::MYSQL);
140 $this->version = $bearsamppConfig->getRaw(self::ROOT_CFG_VERSION);
141 parent::reload($id, $type);
142
143 $this->enable = $this->enable && $bearsamppConfig->getRaw(self::ROOT_CFG_ENABLE);
144 $this->service = new Win32Service(self::SERVICE_NAME);
145 $this->errorLog = Path::getLogsPath() . '/mysql.log';
146
147 if ($this->bearsamppConfRaw !== false) {
148 $this->exe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_EXE];
149 $this->conf = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CONF];
150 $this->port = $this->bearsamppConfRaw[self::LOCAL_CFG_PORT];
151 $this->rootUser = isset($this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_USER]) ? $this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_USER] : 'root';
152 $this->rootPwd = isset($this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_PWD]) ? $this->bearsamppConfRaw[self::LOCAL_CFG_ROOT_PWD] : '';
153 $this->cliExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CLI_EXE];
154 $this->admin = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_ADMIN];
155 $this->dataDir = $this->symlinkPath . '/data';
156 }
157
158 if (!$this->enable) {
159 Log::info($this->name . ' is not enabled!');
160
161 return;
162 }
163 if (!is_dir($this->currentPath)) {
164 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->currentPath));
165
166 return;
167 }
168 if (!is_dir($this->symlinkPath)) {
169 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->symlinkPath));
170
171 return;
172 }
173 if (!is_file($this->bearsamppConf)) {
174 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->bearsamppConf));
175
176 return;
177 }
178 if (!is_file($this->exe)) {
179 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->exe));
180
181 return;
182 }
183 if (!is_file($this->conf)) {
184 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->conf));
185
186 return;
187 }
188 if (!is_numeric($this->port) || $this->port <= 0) {
189 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_PORT, $this->port));
190
191 return;
192 }
193 if (empty($this->rootUser)) {
194 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_ROOT_USER, $this->rootUser));
195
196 return;
197 }
198 if (!is_file($this->cliExe)) {
199 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->cliExe));
200
201 return;
202 }
203 if (!is_file($this->admin)) {
204 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->admin));
205
206 return;
207 }
208
209 $this->service->setDisplayName(APP_TITLE . ' ' . $this->getName());
210 $this->service->setBinPath($this->exe);
211 $this->service->setParams(self::SERVICE_NAME);
212 $this->service->setStartType(Win32Service::SERVICE_DEMAND_START);
213 $this->service->setErrorControl(Win32Service::SERVER_ERROR_NORMAL);
214 }
215
221 protected function replaceAll($params)
222 {
223 $content = file_get_contents($this->bearsamppConf);
224
225 foreach ($params as $key => $value) {
226 $content = preg_replace('|' . $key . ' = .*|', $key . ' = ' . '"' . $value . '"', $content);
227 $this->bearsamppConfRaw[$key] = $value;
228 switch ($key) {
229 case self::LOCAL_CFG_PORT:
230 $this->port = $value;
231 break;
232 case self::LOCAL_CFG_ROOT_USER:
233 $this->rootUser = $value;
234 break;
235 case self::LOCAL_CFG_ROOT_PWD:
236 $this->rootPwd = $value;
237 break;
238 }
239 }
240
241 file_put_contents($this->bearsamppConf, $content);
242
243 self::invalidateConfigCacheForPath($this->bearsamppConf);
244 }
245
255 public function changePort($port, $checkUsed = false, $wbProgressBar = null)
256 {
257 global $bearsamppWinbinder;
258
259 if (!Util::isValidPort($port)) {
260 Log::error($this->getName() . ' port not valid: ' . $port);
261
262 return false;
263 }
264
265 $port = intval($port);
266 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
267
268 $isPortInUse = ServiceHelper::isPortInUse($port);
269 if (!$checkUsed || $isPortInUse === false) {
270 // bearsampp.conf
271 $this->setPort($port);
272 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
273
274 // conf
275 $this->update();
276 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
277
278 return true;
279 }
280
281 Log::debug($this->getName() . ' port in used: ' . $port . ' - ' . $isPortInUse);
282
283 return $isPortInUse;
284 }
285
294 public function checkPort($port, $showWindow = false)
295 {
296 global $bearsamppLang, $bearsamppWinbinder;
297 $boxTitle = sprintf($bearsamppLang->getValue(Lang::CHECK_PORT_TITLE), $this->getName(), $port);
298 $startTime = microtime(true);
299
300 if (!Util::isValidPort($port)) {
301 Log::error($this->getName() . ' port not valid: ' . $port);
302
303 return false;
304 }
305
306 // Quick socket check first - much faster than PDO connection
307 $timeout = 1; // Reduced timeout for better performance
308 $fp = @fsockopen(APP_LOCALHOST, $port, $errno, $errstr, $timeout);
309 if (!$fp) {
310 Log::debug($this->getName() . ' port ' . $port . ' is not used');
311 if ($showWindow) {
312 $bearsamppWinbinder->messageBoxError(
313 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED), $port),
314 $boxTitle
315 );
316 }
317
318 return false;
319 }
320 fclose($fp);
321
322 // Use cached connection if available for better performance
323 static $cachedConnection = null;
324 static $lastPort = null;
325
326 if ($cachedConnection === null || $lastPort !== $port) {
327 try {
328 // Use new constant name for PHP 8.5+ while maintaining backward compatibility
329 // Check PHP version to avoid deprecation warnings
330 if (PHP_VERSION_ID >= 80500) {
331 $initCommandAttr = \Pdo\Mysql::ATTR_INIT_COMMAND;
332 } else {
333 $initCommandAttr = \PDO::MYSQL_ATTR_INIT_COMMAND;
334 }
335
336 $options = [
337 \PDO::ATTR_TIMEOUT => $timeout,
338 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
339 $initCommandAttr => "SET SESSION sql_mode=''"
340 ];
341
342 $dsn = 'mysql:host=' . APP_LOCALHOST . ';port=' . $port;
343 $cachedConnection = new \PDO($dsn, $this->rootUser, $this->rootPwd, $options);
344 $lastPort = $port;
345 } catch (\PDOException $e) {
346 Log::debug($this->getName() . ' port ' . $port . ' connection failed: ' . $e->getMessage());
347 if ($showWindow) {
348 $bearsamppWinbinder->messageBoxWarning(
349 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED_BY), $port),
350 $boxTitle
351 );
352 }
353
354 return false;
355 }
356 }
357
358 try {
359 // Single optimized query to get both version and type
360 $stmt = $cachedConnection->query("SELECT @@version, @@version_comment");
361 $row = $stmt->fetch(\PDO::FETCH_NUM);
362
363 if (!$row) {
364 return false;
365 }
366
367 $version = explode('-', $row[0]);
368 $version = count($version) > 1 ? $version[0] : $row[0];
369 $isMysql = UtilString::startWith(strtolower($row[1]), 'mysql');
370
371 if (!$isMysql) {
372 Log::debug($this->getName() . ' port used by another DBMS: ' . $port);
373 if ($showWindow) {
374 $bearsamppWinbinder->messageBoxWarning(
376 $boxTitle
377 );
378 }
379
380 return false;
381 }
382
383 Log::debug($this->getName() . ' port ' . $port . ' is used by: ' . $this->getName() . ' ' . $version);
384 if ($showWindow) {
385 $bearsamppWinbinder->messageBoxInfo(
386 sprintf($bearsamppLang->getValue(Lang::PORT_USED_BY), $port, $this->getName() . ' ' . $version),
387 $boxTitle
388 );
389 }
390
391 $totalTime = round(microtime(true) - $startTime, 2);
392 Log::trace("MySQL port check completed in {$totalTime}s");
393
394 return true;
395 } catch (\PDOException $e) {
396 Log::debug($this->getName() . ' port ' . $port . ' validation error: ' . $e->getMessage());
397 if ($showWindow) {
398 $bearsamppWinbinder->messageBoxWarning(
399 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED_BY), $port),
400 $boxTitle
401 );
402 }
403
404 return false;
405 }
406 }
407
417 public function changeRootPassword($currentPwd, $newPwd, $wbProgressBar = null)
418 {
419 global $bearsamppWinbinder;
420 $startTime = microtime(true);
421 $error = null;
422 $timeout = 5; // 5 seconds timeout
423
424 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
425
426 try {
427 // Connect using PDO
428 $options = [
429 \PDO::ATTR_TIMEOUT => $timeout,
430 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
431 ];
432
433 $dsn = 'mysql:host=' . APP_LOCALHOST . ';port=' . $this->port;
434 $dbLink = new \PDO($dsn, $this->rootUser, $currentPwd, $options);
435
436 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
437
438 // Determine MySQL version to use appropriate password update syntax
439 $stmt = $dbLink->query('SELECT VERSION()');
440 $version = $stmt->fetchColumn();
441
442 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
443
444 // Use appropriate SQL syntax based on MySQL version
445 if (version_compare($version, '5.7.6', '>=')) {
446 // MySQL 5.7.6 and newer uses ALTER USER
447 $sql = "ALTER USER '{$this->rootUser}'@'localhost' IDENTIFIED BY :password";
448 $stmt = $dbLink->prepare($sql);
449 $stmt->bindParam(':password', $newPwd);
450 } else {
451 // Older versions use SET PASSWORD
452 $sql = "SET PASSWORD FOR '{$this->rootUser}'@'localhost' = PASSWORD(:password)";
453 $stmt = $dbLink->prepare($sql);
454 $stmt->bindParam(':password', $newPwd);
455 }
456
457 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
458 $stmt->execute();
459
460 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
461 $dbLink->query('FLUSH PRIVILEGES');
462
463 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
464 $dbLink = null; // Close connection properly
465
466 } catch (\PDOException $e) {
467 $error = $e->getMessage();
468 }
469
470 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
471
472 if (!empty($error)) {
473 $totalTime = round(microtime(true) - $startTime, 2);
474 Log::trace("MySQL password change failed in {$totalTime}s: " . $error);
475
476 return $error;
477 }
478
479 // bearsampp.conf
480 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
481 $this->setRootPwd($newPwd);
482
483 // conf
484 $this->update();
485 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
486
487 $totalTime = round(microtime(true) - $startTime, 2);
488 Log::trace("MySQL password change completed in {$totalTime}s");
489
490 return true;
491 }
492
501 public function checkRootPassword($currentPwd = null, $wbProgressBar = null)
502 {
503 global $bearsamppWinbinder;
504 $startTime = microtime(true);
505 $currentPwd = $currentPwd == null ? $this->rootPwd : $currentPwd;
506 $error = null;
507 $timeout = 2; // Reduced timeout for faster validation
508
509 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
510
511 // Use cached connection for password validation if available
512 static $passwordCache = [];
513 $cacheKey = md5($this->rootUser . ':' . $currentPwd . ':' . $this->port);
514
515 if (isset($passwordCache[$cacheKey]) && (time() - $passwordCache[$cacheKey]['time']) < 30) {
516 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
517 $totalTime = round(microtime(true) - $startTime, 2);
518 Log::trace("MySQL password check completed from cache in {$totalTime}s");
519
520 return $passwordCache[$cacheKey]['result'];
521 }
522
523 try {
524 // Use new constant name for PHP 8.5+ while maintaining backward compatibility
525 // Check PHP version to avoid deprecation warnings
526 if (PHP_VERSION_ID >= 80500) {
527 $initCommandAttr = \Pdo\Mysql::ATTR_INIT_COMMAND;
528 } else {
529 $initCommandAttr = \PDO::MYSQL_ATTR_INIT_COMMAND;
530 }
531
532 $options = [
533 \PDO::ATTR_TIMEOUT => $timeout,
534 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
535 $initCommandAttr => "SET SESSION sql_mode=''"
536 ];
537
538 $dsn = 'mysql:host=' . APP_LOCALHOST . ';port=' . $this->port;
539 $dbLink = new \PDO($dsn, $this->rootUser, $currentPwd, $options);
540
541 // Quick validation query
542 $dbLink->query('SELECT 1');
543 $dbLink = null; // Close connection properly
544
545 // Cache successful result
546 $passwordCache[$cacheKey] = [
547 'result' => true,
548 'time' => time()
549 ];
550 } catch (\PDOException $e) {
551 $error = $e->getMessage();
552
553 // Cache failed result for shorter time
554 $passwordCache[$cacheKey] = [
555 'result' => $error,
556 'time' => time() - 25 // Cache for only 5 seconds
557 ];
558 }
559
560 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
561
562 if (!empty($error)) {
563 $totalTime = round(microtime(true) - $startTime, 2);
564 Log::trace("MySQL password check failed in {$totalTime}s: " . $error);
565
566 return $error;
567 }
568
569 $totalTime = round(microtime(true) - $startTime, 2);
570 Log::trace("MySQL password check completed in {$totalTime}s");
571
572 return true;
573 }
574
583 public function switchVersion($version, $showWindow = false)
584 {
585 Log::debug('Switch ' . $this->name . ' version to ' . $version);
586
587 return $this->updateConfig($version, 0, $showWindow);
588 }
589
599 protected function updateConfig($version = null, $sub = 0, $showWindow = false)
600 {
601 global $bearsamppLang, $bearsamppBins, $bearsamppApps, $bearsamppWinbinder;
602
603 if (!$this->enable) {
604 return true;
605 }
606
607 $version = $version == null ? $this->version : $version;
608 Log::debug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'Update ' . $this->name . ' ' . $version . ' config');
609
610 $boxTitle = sprintf($bearsamppLang->getValue(Lang::SWITCH_VERSION_TITLE), $this->getName(), $version);
611
612 $currentPath = str_replace('mysql' . $this->getVersion(), 'mysql' . $version, Path::getModuleCurrentPath($this));
613 $conf = str_replace('mysql' . $this->getVersion(), 'mysql' . $version, $this->getConf());
614 $bearsamppConf = str_replace('mysql' . $this->getVersion(), 'mysql' . $version, $this->bearsamppConf);
615
616 if ($this->version != $version) {
618 }
619
620 if (!file_exists($conf) || !file_exists($bearsamppConf)) {
621 Log::error('bearsampp config files not found for ' . $this->getName() . ' ' . $version);
622 if ($showWindow) {
623 $bearsamppWinbinder->messageBoxError(
624 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_NOT_FOUND_ERROR), $this->getName() . ' ' . $version),
625 $boxTitle
626 );
627 }
628
629 return false;
630 }
631
632 $bearsamppConfRaw = parse_ini_file($bearsamppConf);
633 if ($bearsamppConfRaw === false || !isset($bearsamppConfRaw[self::ROOT_CFG_VERSION]) || $bearsamppConfRaw[self::ROOT_CFG_VERSION] != $version) {
634 Log::error('bearsampp config file malformed for ' . $this->getName() . ' ' . $version);
635 if ($showWindow) {
636 $bearsamppWinbinder->messageBoxError(
637 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_MALFORMED_ERROR), $this->getName() . ' ' . $version),
638 $boxTitle
639 );
640 }
641
642 return false;
643 }
644
645 // bearsampp.conf
646 $this->setVersion($version);
647
648 // Invalidate cache for the new version's config
650
651 // conf
652 Util::replaceInFile($this->getConf(), array(
653 '/^port(.*?)=(.*?)(\d+)/' => 'port = ' . $this->port
654 ));
655
656 // phpmyadmin
657 $bearsamppApps->getPhpmyadmin()->update($sub + 1);
658
659 // php
660 $bearsamppBins->getPhp()->update($sub + 1);
661
662 return true;
663 }
664
674 public function initData($path = null, $version = null)
675 {
676 Log::trace('Starting MySQL data initialization');
677 $startTime = microtime(true);
678
679 $path = $path != null ? $path : Path::getModuleCurrentPath($this);
680 $version = $version != null ? $version : $this->getVersion();
681 $dataDir = $path . '/data';
682 $perfSchemaDir = $dataDir . '/performance_schema';
683
684 if (version_compare($version, '5.7.0', '<')) {
685 Log::trace('MySQL version below 5.7.0, skipping initialization');
686
687 return true;
688 }
689
690 $needsInit = false;
691
692 if (!is_dir($dataDir)) {
693 Log::trace('MySQL data directory does not exist; initialization required');
694 $needsInit = true;
695 } else {
696 if (!is_dir($perfSchemaDir)) {
697 Log::trace('performance_schema directory missing; reinitialization required');
698 $needsInit = true;
699 }
700 }
701
702 if (!$needsInit) {
703 Log::trace('MySQL data directory already initialized');
704
705 return true;
706 }
707
708 // Prepare a clean data directory (mysqld --initialize-insecure requires an empty/nonexistent directory)
709 if (is_dir($dataDir)) {
710 $backupDir = $dataDir . '_bak_' . date('Ymd_His');
711 if (@rename($dataDir, $backupDir)) {
712 Log::trace('Backed up existing data directory to: ' . $backupDir);
713 } else {
714 Log::trace('Failed to backup existing data directory; attempting to clear it');
715 try {
716 $it = new \RecursiveDirectoryIterator($dataDir, \FilesystemIterator::SKIP_DOTS);
717 $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
718 foreach ($files as $file) {
719 if ($file->isDir()) {
720 @rmdir($file->getPathname());
721 } else {
722 @unlink($file->getPathname());
723 }
724 }
725 @rmdir($dataDir);
726 } catch (\Throwable $t) {
727 Log::trace('Error clearing data directory: ' . $t->getMessage());
728 }
729 }
730 }
731
732 if (!is_dir($dataDir)) {
733 @mkdir($dataDir, 0777, true);
734 Log::trace('Created clean MySQL data directory');
735 }
736
737 // Use Bearsampp built-in initialization (init.bat via Batch)
738 try {
740 } catch (\Throwable $e) {
741 Log::trace('Error during MySQL initialization via Batch: ' . $e->getMessage());
742
743 return false;
744 }
745
746 // Verify initialization by checking performance_schema existence
747 if (!is_dir($perfSchemaDir)) {
748 Log::trace('MySQL initialization appears to have failed: performance_schema still missing');
749
750 return false;
751 }
752
753 $totalTime = round(microtime(true) - $startTime, 2);
754 Log::trace("MySQL initialization completed in {$totalTime}s");
755
756 return true;
757 }
758
766 public function getCmdLineOutput($cmd)
767 {
768 $result = array(
769 'syntaxOk' => false,
770 'content' => null,
771 );
772
773 $bin = $this->getExe();
774 $removeLines = 0;
775 $outputFrom = '';
776 if ($cmd == self::CMD_SYNTAX_CHECK) {
777 $outputFrom = '2';
778 } elseif ($cmd == self::CMD_VARIABLES) {
779 $bin = $this->getAdmin();
780 $cmd .= ' --user=' . $this->getRootUser();
781 if ($this->getRootPwd()) {
782 $cmd .= ' --password=' . $this->getRootPwd();
783 }
784 $removeLines = 2;
785 }
786
787 if (file_exists($bin)) {
788 $tmpResult = Batch::exec('mysqlGetCmdLineOutput', '"' . $bin . '" ' . $cmd . ' ' . $outputFrom, 5);
789 if ($tmpResult !== false && is_array($tmpResult)) {
790 $result['syntaxOk'] = empty($tmpResult) || !UtilString::contains(trim($tmpResult[count($tmpResult) - 1]), '[ERROR]');
791 for ($i = 0; $i < $removeLines; $i++) {
792 unset($tmpResult[$i]);
793 }
794 $result['content'] = trim(str_replace($bin, '', implode(PHP_EOL, $tmpResult)));
795 }
796 }
797
798 return $result;
799 }
800
806 public function setVersion($version)
807 {
808 global $bearsamppConfig;
809 $this->version = $version;
810 $bearsamppConfig->replace(self::ROOT_CFG_VERSION, $version);
811 $this->reload();
812 }
813
819 public function getService()
820 {
821 return $this->service;
822 }
823
830 public function setEnable($enabled, $showWindow = false)
831 {
832 global $bearsamppConfig, $bearsamppLang, $bearsamppWinbinder;
833
834 if ($enabled == Config::ENABLED && !is_dir($this->currentPath)) {
835 Log::debug($this->getName() . ' cannot be enabled because bundle ' . $this->getVersion() . ' does not exist in ' . $this->currentPath);
836 if ($showWindow) {
837 $bearsamppWinbinder->messageBoxError(
838 sprintf($bearsamppLang->getValue(Lang::ENABLE_BUNDLE_NOT_EXIST), $this->getName(), $this->getVersion(), $this->currentPath),
839 sprintf($bearsamppLang->getValue(Lang::ENABLE_TITLE), $this->getName())
840 );
841 }
842 $enabled = Config::DISABLED;
843 }
844
845 Log::info($this->getName() . ' switched to ' . ($enabled == Config::ENABLED ? 'enabled' : 'disabled'));
846 $this->enable = $enabled == Config::ENABLED;
847 $bearsamppConfig->replace(self::ROOT_CFG_ENABLE, $enabled);
848
849 $this->reload();
850 if ($this->enable) {
851 ServiceHelper::installService($this, $this->port, self::CMD_SYNTAX_CHECK, $showWindow);
852 } else {
853 ServiceHelper::removeService($this->service, $this->name);
854 }
855 }
856
862 public function getErrorLog()
863 {
864 return $this->errorLog;
865 }
866
872 public function getExe()
873 {
874 return $this->exe;
875 }
876
882 public function getConf()
883 {
884 return $this->conf;
885 }
886
892 public function getPort()
893 {
894 return $this->port;
895 }
896
902 public function setPort($port)
903 {
904 $this->replace(self::LOCAL_CFG_PORT, $port);
905 }
906
912 public function getRootUser()
913 {
914 return $this->rootUser;
915 }
916
922 public function setRootUser($rootUser)
923 {
924 $this->replace(self::LOCAL_CFG_ROOT_USER, $rootUser);
925 }
926
932 public function getRootPwd()
933 {
934 return $this->rootPwd;
935 }
936
942 public function setRootPwd($rootPwd)
943 {
944 $this->replace(self::LOCAL_CFG_ROOT_PWD, $rootPwd);
945 }
946
952 public function getCliExe()
953 {
954 return $this->cliExe;
955 }
956
962 public function getAdmin()
963 {
964 return $this->admin;
965 }
966
972 public function getDataDir()
973 {
974 return $this->dataDir;
975 }
976}
$result
global $bearsamppBins
global $bearsamppLang
global $bearsamppRoot
static initializeMysql($path)
static exec($basename, $content, $timeout=true, $catchOutput=true, $standalone=false, $silent=true, $rebuild=true)
const LOCAL_CFG_EXE
const SERVICE_NAME
const CMD_SYNTAX_CHECK
const CMD_VERSION
replaceAll($params)
updateConfig($version=null, $sub=0, $showWindow=false)
const LOCAL_CFG_ROOT_PWD
const CMD_VARIABLES
getCmdLineOutput($cmd)
const LOCAL_CFG_ROOT_USER
setRootUser($rootUser)
changeRootPassword($currentPwd, $newPwd, $wbProgressBar=null)
switchVersion($version, $showWindow=false)
const LOCAL_CFG_PORT
const ROOT_CFG_ENABLE
setVersion($version)
checkPort($port, $showWindow=false)
changePort($port, $checkUsed=false, $wbProgressBar=null)
setEnable($enabled, $showWindow=false)
const LOCAL_CFG_CONF
const LOCAL_CFG_CLI_EXE
initData($path=null, $version=null)
const LOCAL_CFG_ADMIN
reload($id=null, $type=null)
const ROOT_CFG_VERSION
__construct($id, $type)
checkRootPassword($currentPwd=null, $wbProgressBar=null)
setRootPwd($rootPwd)
const DISABLED
const ENABLED
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 MYSQL
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 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
$options
Definition pearcmd.php:145
const APP_LOCALHOST
Definition root.php:21
const APP_TITLE
Definition root.php:19