Bearsampp 2025.8.29
Loading...
Searching...
No Matches
ActionStartup Class Reference

Public Member Functions

 __construct ($args)
 processWindow ($window, $id, $ctrl, $param1, $param2)

Data Fields

const GAUGE_OTHERS = 19
const GAUGE_SERVICES = 5

Private Member Functions

 changePath ()
 checkApacheServiceWithTimeout ($service)
 checkBinsRegKey ()
 checkBrowser ()
 checkLaunchStartup ()
 checkMySQLServiceWithTimeout ($service, $bin)
 checkPath ()
 checkPathRegKey ()
 checkSystemPathRegKey ()
 cleanOldBehaviors ()
 cleanTmpFolders ()
 createSslCrts ()
 installServices ()
 killOldInstances ()
 refreshAliases ()
 refreshGitRepos ()
 refreshHostname ()
 refreshVhosts ()
 rotationLogs ()
 savePath ()
 scanFolders ()
 sysInfos ()
 updateConfig ()
 writeLog ($log)

Private Attributes

 $error
 $filesToScan
 $restart
 $rootPath
 $splash
 $startTime

Detailed Description

Class ActionStartup Handles the startup process of the Bearsampp application, including initializing services, cleaning temporary files, refreshing configurations, and more.

Definition at line 16 of file class.action.startup.php.

Constructor & Destructor Documentation

◆ __construct()

__construct ( $args)

ActionStartup constructor. Initializes the startup process, including the splash screen and various configurations.

Parameters
array$argsCommand line arguments.

Definition at line 35 of file class.action.startup.php.

36 {
37 global $bearsamppRoot, $bearsamppCore, $bearsamppLang, $bearsamppBins, $bearsamppWinbinder;
38 $this->writeLog( 'Starting ' . APP_TITLE );
39
40 // Init
41 $this->splash = new Splash();
42 $this->restart = false;
43 $this->startTime = Util::getMicrotime();
44 $this->error = '';
45
46 $this->rootPath = $bearsamppRoot->getRootPath();
47 $this->filesToScan = array();
48
49 $gauge = self::GAUGE_SERVICES * count( $bearsamppBins->getServices() );
50 $gauge += self::GAUGE_OTHERS + 1;
51
52 // Start splash screen
53 $this->splash->init(
54 $bearsamppLang->getValue( Lang::STARTUP ),
55 $gauge,
56 sprintf( $bearsamppLang->getValue( Lang::STARTUP_STARTING_TEXT ), APP_TITLE . ' ' . $bearsamppCore->getAppVersion() )
57 );
58
59 $bearsamppWinbinder->setHandler( $this->splash->getWbWindow(), $this, 'processWindow', 1000 );
60 $bearsamppWinbinder->mainLoop();
61 $bearsamppWinbinder->reset();
62 }
global $bearsamppBins
global $bearsamppLang
global $bearsamppRoot
global $bearsamppCore
const STARTUP_STARTING_TEXT
const STARTUP
static getMicrotime()
const APP_TITLE
Definition root.php:13

References $bearsamppBins, $bearsamppCore, $bearsamppLang, $bearsamppRoot, APP_TITLE, Util\getMicrotime(), Lang\STARTUP, Lang\STARTUP_STARTING_TEXT, and writeLog().

Member Function Documentation

◆ changePath()

changePath ( )
private

Changes the application path and logs the number of files and occurrences changed.

Definition at line 664 of file class.action.startup.php.

665 {
666 global $bearsamppLang;
667
668 $this->splash->setTextLoading( sprintf( $bearsamppLang->getValue( Lang::STARTUP_CHANGE_PATH_TEXT ), $this->rootPath ) );
669 $this->splash->incrProgressBar();
670
671 $result = Util::changePath( $this->filesToScan, $this->rootPath );
672 $this->writeLog( 'Nb files changed: ' . $result['countChangedFiles'] );
673 $this->writeLog( 'Nb occurences changed: ' . $result['countChangedOcc'] );
674 }
$result
const STARTUP_CHANGE_PATH_TEXT
static changePath($filesToScan, $rootPath=null)

References $bearsamppLang, $result, Util\changePath(), Lang\STARTUP_CHANGE_PATH_TEXT, and writeLog().

Referenced by processWindow().

◆ checkApacheServiceWithTimeout()

checkApacheServiceWithTimeout ( $service)
private

Specialized method to check Apache service with timeout protection. Apache service checks can sometimes hang, so this method provides a safer way to check.

Parameters
object$serviceThe Apache service object
Returns
mixed Service info array or false if service not installed or check timed out

Definition at line 1129 of file class.action.startup.php.

1130 {
1131 Util::logTrace('Starting specialized Apache service check with timeout protection');
1132
1133 // Set a timeout for the Apache service check
1134 $serviceCheckStartTime = microtime(true);
1135 $serviceCheckTimeout = 10; // 10 seconds timeout
1136
1137 try {
1138 // Use a non-blocking approach to check service
1139 $serviceInfos = false;
1140
1141 // First try a quick check if the service exists in the list
1142 $serviceList = Win32Service::getServices();
1143 if (is_array($serviceList) && isset($serviceList[$service->getName()])) {
1144 Util::logTrace('Apache service found in service list, getting details');
1145
1146 // Service exists, now try to get its details with timeout protection
1147 $startTime = microtime(true);
1148 $serviceInfos = $service->infos();
1149
1150 // Check if we've exceeded our timeout
1151 if (microtime(true) - $serviceCheckStartTime > $serviceCheckTimeout) {
1152 Util::logTrace("Apache service check timeout exceeded, assuming service needs reinstall");
1153 return false;
1154 }
1155 } else {
1156 Util::logTrace('Apache service not found in service list');
1157 return false;
1158 }
1159
1160 return $serviceInfos;
1161 } catch (\Exception $e) {
1162 Util::logTrace("Exception during Apache service check: " . $e->getMessage());
1163 return false;
1164 } catch (\Throwable $e) {
1165 Util::logTrace("Throwable during Apache service check: " . $e->getMessage());
1166 return false;
1167 }
1168 }
static logTrace($data, $file=null)

References $startTime, and Util\logTrace().

Referenced by installServices().

◆ checkBinsRegKey()

checkBinsRegKey ( )
private

Checks and updates the application bins registry key. If the current registry key does not match the generated key, it updates the registry key. Logs the current and generated registry keys. Sets an error message if the registry key update fails. Sets a restart flag if the registry key is updated.

Definition at line 723 of file class.action.startup.php.

724 {
725 global $bearsamppLang, $bearsamppRegistry;
726
727 $this->splash->setTextLoading( sprintf( $bearsamppLang->getValue( Lang::STARTUP_REGISTRY_TEXT ), Registry::APP_BINS_REG_ENTRY ) );
728 $this->splash->incrProgressBar();
729
730 $currentAppBinsRegKey = Util::getAppBinsRegKey();
731 $genAppBinsRegKey = Util::getAppBinsRegKey( false );
732 $this->writeLog( 'Current app bins reg key: ' . $currentAppBinsRegKey );
733 $this->writeLog( 'Gen app bins reg key: ' . $genAppBinsRegKey );
734 if ( $currentAppBinsRegKey != $genAppBinsRegKey ) {
735 if ( !Util::setAppBinsRegKey( $genAppBinsRegKey ) ) {
736 if ( !empty( $this->error ) ) {
737 $this->error .= PHP_EOL . PHP_EOL;
738 }
740 $this->error .= PHP_EOL . $bearsamppRegistry->getLatestError();
741 }
742 else {
743 $this->writeLog( 'Need restart: checkBinsRegKey' );
744 $this->restart = true;
745 }
746 }
747 }
const STARTUP_REGISTRY_ERROR_TEXT
const STARTUP_REGISTRY_TEXT
const APP_BINS_REG_ENTRY
static getAppBinsRegKey($fromRegistry=true)
static setAppBinsRegKey($value)

References $bearsamppLang, Registry\APP_BINS_REG_ENTRY, Util\getAppBinsRegKey(), Util\setAppBinsRegKey(), Lang\STARTUP_REGISTRY_ERROR_TEXT, Lang\STARTUP_REGISTRY_TEXT, and writeLog().

Referenced by processWindow().

◆ checkBrowser()

checkBrowser ( )
private

Checks and sets the default browser configuration.

Definition at line 578 of file class.action.startup.php.

579 {
581
582 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_CHECK_BROWSER_TEXT ) );
583 $this->splash->incrProgressBar();
584 $this->writeLog( 'Check browser' );
585
586 $currentBrowser = $bearsamppConfig->getBrowser();
587 if ( empty( $currentBrowser ) || !file_exists( $currentBrowser ) ) {
589 }
590 }
const CFG_BROWSER
const STARTUP_CHECK_BROWSER_TEXT
static getDefaultBrowser()
Definition class.vbs.php:81
global $bearsamppConfig
Definition homepage.php:27

References $bearsamppConfig, $bearsamppLang, Config\CFG_BROWSER, Vbs\getDefaultBrowser(), Lang\STARTUP_CHECK_BROWSER_TEXT, and writeLog().

Referenced by processWindow().

◆ checkLaunchStartup()

checkLaunchStartup ( )
private

Checks and sets the launch startup configuration.

Definition at line 561 of file class.action.startup.php.

562 {
563 global $bearsamppConfig;
564
565 $this->writeLog( 'Check launch startup' );
566
567 if ( $bearsamppConfig->isLaunchStartup() ) {
569 }
570 else {
572 }
573 }
static disableLaunchStartup()
static enableLaunchStartup()

References $bearsamppConfig, Util\disableLaunchStartup(), Util\enableLaunchStartup(), and writeLog().

Referenced by processWindow().

◆ checkMySQLServiceWithTimeout()

checkMySQLServiceWithTimeout ( $service,
$bin )
private

Specialized method to check MySQL service with timeout protection. MySQL service checks can sometimes hang, so this method provides a safer way to check.

Parameters
object$serviceThe MySQL service object
object$binThe MySQL bin object
Returns
mixed Service info array or false if service not installed or check timed out

Definition at line 1178 of file class.action.startup.php.

1179 {
1180 Util::logTrace('Starting specialized MySQL service check with timeout protection');
1181
1182 // Set a timeout for the MySQL service check
1183 $serviceCheckStartTime = microtime(true);
1184 $serviceCheckTimeout = 8; // 8 seconds timeout
1185
1186 try {
1187 // Use a non-blocking approach to check service
1188 $serviceInfos = false;
1189
1190 // First check if the service exists in the list
1191 $serviceList = Win32Service::getServices();
1192 if (is_array($serviceList) && isset($serviceList[$service->getName()])) {
1193 Util::logTrace('MySQL service found in service list, getting details');
1194
1195 // Service exists, now try to get its details with timeout protection
1196 $serviceInfos = $service->infos();
1197
1198 // Check if we've exceeded our timeout
1199 if (microtime(true) - $serviceCheckStartTime > $serviceCheckTimeout) {
1200 Util::logTrace("MySQL service check timeout exceeded, assuming service needs reinstall");
1201 return false;
1202 }
1203 } else {
1204 Util::logTrace('MySQL service not found in service list');
1205 return false;
1206 }
1207
1208 return $serviceInfos;
1209 } catch (\Exception $e) {
1210 Util::logTrace("Exception during MySQL service check: " . $e->getMessage());
1211 return false;
1212 } catch (\Throwable $e) {
1213 Util::logTrace("Throwable during MySQL service check: " . $e->getMessage());
1214 return false;
1215 }
1216 }

References Util\logTrace().

Referenced by installServices().

◆ checkPath()

checkPath ( )
private

Checks the application path and logs the last path content.

Definition at line 637 of file class.action.startup.php.

638 {
640
641 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_CHECK_PATH_TEXT ) );
642 $this->splash->incrProgressBar();
643
644 $this->writeLog( 'Last path: ' . $bearsamppCore->getLastPathContent() );
645 }
const STARTUP_CHECK_PATH_TEXT

References $bearsamppCore, $bearsamppLang, Lang\STARTUP_CHECK_PATH_TEXT, and writeLog().

Referenced by processWindow().

◆ checkPathRegKey()

checkPathRegKey ( )
private

Checks and updates the application path registry key.

Definition at line 690 of file class.action.startup.php.

691 {
692 global $bearsamppRoot, $bearsamppLang, $bearsamppRegistry;
693
694 $this->splash->setTextLoading( sprintf( $bearsamppLang->getValue( Lang::STARTUP_REGISTRY_TEXT ), Registry::APP_PATH_REG_ENTRY ) );
695 $this->splash->incrProgressBar();
696
697 $currentAppPathRegKey = Util::getAppPathRegKey();
698 $genAppPathRegKey = Util::formatWindowsPath( $bearsamppRoot->getRootPath() );
699 $this->writeLog( 'Current app path reg key: ' . $currentAppPathRegKey );
700 $this->writeLog( 'Gen app path reg key: ' . $genAppPathRegKey );
701 if ( $currentAppPathRegKey != $genAppPathRegKey ) {
702 if ( !Util::setAppPathRegKey( $genAppPathRegKey ) ) {
703 if ( !empty( $this->error ) ) {
704 $this->error .= PHP_EOL . PHP_EOL;
705 }
707 $this->error .= PHP_EOL . $bearsamppRegistry->getLatestError();
708 }
709 else {
710 $this->writeLog( 'Need restart: checkPathRegKey' );
711 $this->restart = true;
712 }
713 }
714 }
const APP_PATH_REG_ENTRY
static setAppPathRegKey($value)
static getAppPathRegKey()
static formatWindowsPath($path)

References $bearsamppLang, $bearsamppRoot, Registry\APP_PATH_REG_ENTRY, Util\formatWindowsPath(), Util\getAppPathRegKey(), Util\setAppPathRegKey(), Lang\STARTUP_REGISTRY_ERROR_TEXT, Lang\STARTUP_REGISTRY_TEXT, and writeLog().

Referenced by processWindow().

◆ checkSystemPathRegKey()

checkSystemPathRegKey ( )
private

Checks and updates the system PATH registry key. Ensures the application bins registry entry is at the beginning of the system PATH. Logs the current and new system PATH. Sets an error message if the system PATH update fails. Sets a restart flag if the system PATH is updated.

Definition at line 756 of file class.action.startup.php.

757 {
758 global $bearsamppLang, $bearsamppRegistry;
759
760 $this->splash->setTextLoading( sprintf( $bearsamppLang->getValue( Lang::STARTUP_REGISTRY_TEXT ), Registry::SYSPATH_REG_ENTRY ) );
761 $this->splash->incrProgressBar();
762
763 $currentSysPathRegKey = Util::getSysPathRegKey();
764 $this->writeLog( 'Current system PATH: ' . $currentSysPathRegKey );
765
766 $newSysPathRegKey = str_replace( '%' . Registry::APP_BINS_REG_ENTRY . '%;', '', $currentSysPathRegKey );
767 $newSysPathRegKey = str_replace( '%' . Registry::APP_BINS_REG_ENTRY . '%', '', $newSysPathRegKey );
768 $newSysPathRegKey = '%' . Registry::APP_BINS_REG_ENTRY . '%;' . $newSysPathRegKey;
769 $this->writeLog( 'New system PATH: ' . $newSysPathRegKey );
770
771 if ( $currentSysPathRegKey != $newSysPathRegKey ) {
772 if ( !Util::setSysPathRegKey( $newSysPathRegKey ) ) {
773 if ( !empty( $this->error ) ) {
774 $this->error .= PHP_EOL . PHP_EOL;
775 }
777 $this->error .= PHP_EOL . $bearsamppRegistry->getLatestError();
778 }
779 else {
780 $this->writeLog( 'Need restart: checkSystemPathRegKey' );
781 $this->restart = true;
782 }
783 }
784 else {
785 $this->writeLog( 'Refresh system PATH: ' . $currentSysPathRegKey );
786 Util::setSysPathRegKey( str_replace( '%' . Registry::APP_BINS_REG_ENTRY . '%', '', $currentSysPathRegKey ) );
787 Util::setSysPathRegKey( $currentSysPathRegKey );
788 }
789 }
const SYSPATH_REG_ENTRY
static setSysPathRegKey($value)
static getSysPathRegKey()

References $bearsamppLang, Registry\APP_BINS_REG_ENTRY, Util\getSysPathRegKey(), Util\setSysPathRegKey(), Lang\STARTUP_REGISTRY_ERROR_TEXT, Lang\STARTUP_REGISTRY_TEXT, Registry\SYSPATH_REG_ENTRY, and writeLog().

Referenced by processWindow().

◆ cleanOldBehaviors()

cleanOldBehaviors ( )
private

Cleans old behaviors by removing outdated registry entries.

Definition at line 492 of file class.action.startup.php.

493 {
494 global $bearsamppLang, $bearsamppRegistry;
495
496 $this->writeLog( 'Clean old behaviors' );
497
498 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_CLEAN_OLD_BEHAVIORS_TEXT ) );
499 $this->splash->incrProgressBar();
500
501 // App >= 1.0.13
502 $bearsamppRegistry->deleteValue(
504 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run',
506 );
507 }
const STARTUP_CLEAN_OLD_BEHAVIORS_TEXT
const HKEY_LOCAL_MACHINE

References $bearsamppLang, APP_TITLE, Registry\HKEY_LOCAL_MACHINE, Lang\STARTUP_CLEAN_OLD_BEHAVIORS_TEXT, and writeLog().

Referenced by processWindow().

◆ cleanTmpFolders()

cleanTmpFolders ( )
private

Cleans temporary folders by removing unnecessary files.

Definition at line 477 of file class.action.startup.php.

478 {
480
481 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_CLEAN_TMP_TEXT ) );
482 $this->splash->incrProgressBar();
483
484 $this->writeLog( 'Clear tmp folders' );
485 Util::clearFolder( $bearsamppRoot->getTmpPath(), array('cachegrind', 'composer', 'openssl', 'mailpit', 'xlight', 'npm-cache', 'pip', '.gitignore') );
486 Util::clearFolder( $bearsamppCore->getTmpPath(), array('.gitignore') );
487 }
const STARTUP_CLEAN_TMP_TEXT
static clearFolder($path, $exclude=array())

References $bearsamppCore, $bearsamppLang, $bearsamppRoot, Util\clearFolder(), Lang\STARTUP_CLEAN_TMP_TEXT, and writeLog().

Referenced by processWindow().

◆ createSslCrts()

createSslCrts ( )
private

Creates SSL certificates if they do not already exist. Logs the creation process.

Definition at line 812 of file class.action.startup.php.

813 {
814 global $bearsamppLang, $bearsamppOpenSsl;
815
816 $this->splash->incrProgressBar();
817 if ( !$bearsamppOpenSsl->existsCrt( 'localhost' ) ) {
818 $this->splash->setTextLoading( sprintf( $bearsamppLang->getValue( Lang::STARTUP_GEN_SSL_CRT_TEXT ), 'localhost' ) );
819 $bearsamppOpenSsl->createCrt( 'localhost' );
820 }
821 }
const STARTUP_GEN_SSL_CRT_TEXT

References $bearsamppLang, and Lang\STARTUP_GEN_SSL_CRT_TEXT.

Referenced by processWindow().

◆ installServices()

installServices ( )
private

Installs and starts services for the application. Checks if services are already installed and updates them if necessary. Logs the installation process and any errors encountered.

Definition at line 829 of file class.action.startup.php.

830 {
832
833 Util::logTrace('Starting installServices method');
834
835 if (!$this->restart) {
836 Util::logTrace('Normal startup mode - processing services');
837
838 foreach ($bearsamppBins->getServices() as $sName => $service) {
839 $serviceError = '';
840 $serviceRestart = false;
841 $serviceAlreadyInstalled = false;
842 $serviceToRemove = false;
843 $startServiceTime = Util::getMicrotime();
844
845 Util::logTrace('Processing service: ' . $sName);
846
847 $syntaxCheckCmd = null;
848 $bin = null;
849 $port = 0;
850 if ($sName == BinMailpit::SERVICE_NAME) {
851 $bin = $bearsamppBins->getMailpit();
852 $port = $bearsamppBins->getMailpit()->getSmtpPort();
853 Util::logTrace('Service identified as Mailpit, port: ' . $port);
854 } elseif ($sName == BinMemcached::SERVICE_NAME) {
855 $bin = $bearsamppBins->getMemcached();
856 $port = $bearsamppBins->getMemcached()->getPort();
857 Util::logTrace('Service identified as Memcached, port: ' . $port);
858 } elseif ($sName == BinApache::SERVICE_NAME) {
859 $bin = $bearsamppBins->getApache();
860 $port = $bearsamppBins->getApache()->getPort();
861 $syntaxCheckCmd = BinApache::CMD_SYNTAX_CHECK;
862 Util::logTrace('Service identified as Apache, port: ' . $port);
863 } elseif ($sName == BinMysql::SERVICE_NAME) {
864 $bin = $bearsamppBins->getMysql();
865 $port = $bearsamppBins->getMysql()->getPort();
866 $syntaxCheckCmd = BinMysql::CMD_SYNTAX_CHECK;
867 Util::logTrace('Service identified as MySQL, port: ' . $port);
868
869 // Pre-initialize MySQL data if needed
870 if (!file_exists($bin->getDataDir()) || count(glob($bin->getDataDir() . '/*')) === 0) {
871 Util::logTrace('Pre-initializing MySQL data directory');
872 $this->splash->setTextLoading(sprintf($bearsamppLang->getValue(Lang::STARTUP_CHECK_SERVICE_TEXT), $name . ' (initializing data)'));
873 $bin->initData();
874 }
875 } elseif ($sName == BinMariadb::SERVICE_NAME) {
876 $bin = $bearsamppBins->getMariadb();
877 $port = $bearsamppBins->getMariadb()->getPort();
878 $syntaxCheckCmd = BinMariadb::CMD_SYNTAX_CHECK;
879 Util::logTrace('Service identified as MariaDB, port: ' . $port);
880 } elseif ($sName == BinPostgresql::SERVICE_NAME) {
881 $bin = $bearsamppBins->getPostgresql();
882 $port = $bearsamppBins->getPostgresql()->getPort();
883 Util::logTrace('Service identified as PostgreSQL, port: ' . $port);
884 } elseif ($sName == BinXlight::SERVICE_NAME) {
885 $bin = $bearsamppBins->getXlight();
886 $port = $bearsamppBins->getXlight()->getPort();
887 Util::logTrace('Service identified as Xlight, port: ' . $port);
888 }
889
890 $name = $bin->getName() . ' ' . $bin->getVersion() . ' (' . $service->getName() . ')';
891 Util::logTrace('Full service name: ' . $name);
892
893 $this->splash->incrProgressBar();
894 $this->splash->setTextLoading(sprintf($bearsamppLang->getValue(Lang::STARTUP_CHECK_SERVICE_TEXT), $name));
895
896 Util::logTrace('Checking if service is already installed');
897
898 // Add a timeout for the service check operation
899 $serviceCheckStartTime = microtime(true);
900 $serviceCheckTimeout = 15; // 15 seconds timeout
901
902 // Use specialized check for Apache and MySQL services due to known issues with hanging
903 if ($sName == BinApache::SERVICE_NAME) {
904 Util::logTrace('Using specialized Apache service check');
905 $serviceInfos = $this->checkApacheServiceWithTimeout($service);
906 } else if ($sName == BinMysql::SERVICE_NAME) {
907 Util::logTrace('Using specialized MySQL service check');
908 $serviceInfos = $this->checkMySQLServiceWithTimeout($service, $bin);
909
910 // If service exists but is hanging, force restart
911 if ($serviceInfos === false && $service->isInstalled()) {
912 Util::logTrace('MySQL service appears to be hanging, forcing restart');
913 Win32Ps::killBins(['mysqld.exe']);
914 $service->delete();
915 $serviceToRemove = true;
916 }
917 } else {
918 try {
919 // Call infos() with a timeout check for other services
920 $serviceInfos = $service->infos();
921
922 // Check if we've exceeded our timeout
923 if (microtime(true) - $serviceCheckStartTime > $serviceCheckTimeout) {
924 Util::logTrace("Service check timeout exceeded, assuming service is not installed");
925 $serviceInfos = false;
926 }
927 } catch (\Exception $e) {
928 Util::logTrace("Exception during service check: " . $e->getMessage() . ", assuming service is not installed");
929 $serviceInfos = false;
930 } catch (\Throwable $e) {
931 Util::logTrace("Throwable during service check: " . $e->getMessage() . ", assuming service is not installed");
932 $serviceInfos = false;
933 }
934 }
935 if ($serviceInfos !== false) {
936 $serviceAlreadyInstalled = true;
937 $this->writeLog($name . ' service already installed');
938 Util::logTrace('Service already installed, retrieving details');
939
940 foreach ($serviceInfos as $key => $value) {
941 $this->writeLog('-> ' . $key . ': ' . $value);
942 Util::logTrace('Service info - ' . $key . ': ' . $value);
943 }
944
945 // Special handling for PostgreSQL service
946 if ($sName == BinPostgresql::SERVICE_NAME) {
947 // For PostgreSQL, only compare the executable path, not the parameters
948 $serviceGenPathName = trim(str_replace('"', '', $service->getBinPath()));
949 $installedPathParts = explode(' ', $serviceInfos[Win32Service::VBS_PATH_NAME], 2);
950 $serviceVbsPathName = trim(str_replace('"', '', $installedPathParts[0]));
951
952 Util::logTrace('PostgreSQL service - comparing only executable paths');
953 Util::logTrace('Generated path: ' . $serviceGenPathName);
954 Util::logTrace('Installed path: ' . $serviceVbsPathName);
955 } else {
956 // For other services, use the normal comparison with enhanced debugging
957 $serviceGenPathName = trim(str_replace('"', '', $service->getBinPath() . ($service->getParams() ? ' ' . $service->getParams() : '')));
958 $serviceVbsPathName = trim(str_replace('"', '', $serviceInfos[Win32Service::VBS_PATH_NAME]));
959
960 Util::logTrace('Comparing service paths - Generated: ' . $serviceGenPathName . ' vs Installed: ' . $serviceVbsPathName);
961
962 // Add detailed debugging to identify invisible characters
963 Util::logTrace('Generated path length: ' . strlen($serviceGenPathName));
964 Util::logTrace('Installed path length: ' . strlen($serviceVbsPathName));
965
966 // Output character codes to identify invisible characters
967 $genChars = 'Generated path char codes: ';
968 for ($i = 0; $i < strlen($serviceGenPathName); $i++) {
969 $genChars .= ord($serviceGenPathName[$i]) . ' ';
970 }
971 Util::logTrace($genChars);
972
973 $instChars = 'Installed path char codes: ';
974 for ($i = 0; $i < strlen($serviceVbsPathName); $i++) {
975 $instChars .= ord($serviceVbsPathName[$i]) . ' ';
976 }
977 Util::logTrace($instChars);
978 }
979
980 // Try a more robust comparison that normalizes whitespace
981 $normalizedGenPath = preg_replace('/\s+/', ' ', $serviceGenPathName);
982 $normalizedVbsPath = preg_replace('/\s+/', ' ', $serviceVbsPathName);
983
984 if ($normalizedGenPath === $normalizedVbsPath) {
985 Util::logTrace('Paths match after normalizing whitespace - skipping service reinstall');
986 } else if ($serviceGenPathName != $serviceVbsPathName) {
987 $serviceToRemove = true;
988 $this->writeLog($name . ' service has to be removed');
989 $this->writeLog('-> serviceGenPathName: ' . $serviceGenPathName);
990 $this->writeLog('-> serviceVbsPathName: ' . $serviceVbsPathName);
991 Util::logTrace("Service paths don't match - service will be removed and reinstalled");
992 }
993 } else {
994 Util::logTrace('Service not installed yet');
995 }
996
997 $this->splash->incrProgressBar();
998 if ($serviceToRemove) {
999 Util::logTrace('Attempting to remove service: ' . $name);
1000 if (!$service->delete()) {
1001 Util::logTrace('Failed to remove service, restart required');
1002 $serviceRestart = true;
1003 } else {
1004 Util::logTrace('Service removed successfully');
1005 }
1006 }
1007
1008 if (!$serviceRestart) {
1009 Util::logTrace('Checking if port ' . $port . ' is in use');
1010 $isPortInUse = Util::isPortInUse($port);
1011 if ($isPortInUse === false) {
1012 Util::logTrace('Port ' . $port . ' is available');
1013 $this->splash->incrProgressBar();
1014 if (!$serviceAlreadyInstalled || $serviceToRemove) {
1015 Util::logTrace('Installing new service: ' . $name);
1016 $this->splash->setTextLoading(sprintf($bearsamppLang->getValue(Lang::STARTUP_INSTALL_SERVICE_TEXT), $name));
1017 if (!$service->create()) {
1018 $serviceError .= sprintf($bearsamppLang->getValue(Lang::STARTUP_SERVICE_CREATE_ERROR), $service->getError());
1019 Util::logTrace('Service creation failed: ' . $service->getError());
1020 } else {
1021 Util::logTrace('Service created successfully');
1022 }
1023 }
1024
1025 $this->splash->incrProgressBar();
1026 $this->splash->setTextLoading(sprintf($bearsamppLang->getValue(Lang::STARTUP_START_SERVICE_TEXT), $name));
1027
1028 Util::logTrace('Starting service: ' . $name);
1029 if (!$service->start()) {
1030 if (!empty($serviceError)) {
1031 $serviceError .= PHP_EOL;
1032 }
1033 $serviceError .= sprintf($bearsamppLang->getValue(Lang::STARTUP_SERVICE_START_ERROR), $service->getError());
1034 Util::logTrace('Service start failed: ' . $service->getError());
1035
1036 if (!empty($syntaxCheckCmd)) {
1037 Util::logTrace('Running syntax check command for ' . $name);
1038
1039 // Set a timeout for syntax check
1040 $syntaxCheckStartTime = microtime(true);
1041 $syntaxCheckTimeout = 5; // 5 seconds
1042
1043 try {
1044 $cmdSyntaxCheck = $bin->getCmdLineOutput($syntaxCheckCmd);
1045
1046 // Check if we've exceeded our timeout
1047 if (microtime(true) - $syntaxCheckStartTime > $syntaxCheckTimeout) {
1048 Util::logTrace('Syntax check timeout exceeded, assuming syntax is OK');
1049 $cmdSyntaxCheck = ['syntaxOk' => true];
1050 }
1051
1052 if (!$cmdSyntaxCheck['syntaxOk']) {
1053 $serviceError .= PHP_EOL . sprintf($bearsamppLang->getValue(Lang::STARTUP_SERVICE_SYNTAX_ERROR), $cmdSyntaxCheck['content']);
1054 Util::logTrace('Syntax check failed: ' . $cmdSyntaxCheck['content']);
1055 } else {
1056 Util::logTrace('Syntax check passed but service still failed to start');
1057 }
1058 } catch (\Exception $e) {
1059 Util::logTrace('Exception during syntax check: ' . $e->getMessage());
1060 // Don't add error, just continue
1061 } catch (\Throwable $e) {
1062 Util::logTrace('Throwable during syntax check: ' . $e->getMessage());
1063 // Don't add error, just continue
1064 }
1065 }
1066 } else {
1067 Util::logTrace('Service started successfully');
1068 }
1069 $this->splash->incrProgressBar();
1070 } else {
1071 Util::logTrace('Port ' . $port . ' is already in use by: ' . $isPortInUse);
1072 if (!empty($serviceError)) {
1073 $serviceError .= PHP_EOL;
1074 }
1075 $serviceError .= sprintf($bearsamppLang->getValue(Lang::STARTUP_SERVICE_PORT_ERROR), $port, $isPortInUse);
1076 $this->splash->incrProgressBar(3);
1077 }
1078 } else {
1079 $this->writeLog('Need restart: installService ' . $bin->getName());
1080 Util::logTrace('Restart required for service: ' . $bin->getName());
1081 $this->restart = true;
1082 $this->splash->incrProgressBar(3);
1083 }
1084
1085 if (!empty($serviceError)) {
1086 Util::logTrace('Service error occurred: ' . $serviceError);
1087 if (!empty($this->error)) {
1088 $this->error .= PHP_EOL . PHP_EOL;
1089 }
1090 $this->error .= sprintf($bearsamppLang->getValue(Lang::STARTUP_SERVICE_ERROR), $name) . PHP_EOL . $serviceError;
1091 } else {
1092 $installTime = round(Util::getMicrotime() - $startServiceTime, 3);
1093 $this->writeLog($name . ' service installed in ' . $installTime . 's');
1094 Util::logTrace('Service ' . $name . ' installed successfully in ' . $installTime . ' seconds');
1095 }
1096 }
1097 } else {
1098 Util::logTrace('Restart mode - skipping service installation');
1099 $this->splash->incrProgressBar(self::GAUGE_SERVICES * count($bearsamppBins->getServices()));
1100 }
1101
1102 Util::logTrace('Completed installServices method');
1103 }
$port
checkMySQLServiceWithTimeout($service, $bin)
checkApacheServiceWithTimeout($service)
const CMD_SYNTAX_CHECK
const SERVICE_NAME
const CMD_SYNTAX_CHECK
const STARTUP_START_SERVICE_TEXT
const STARTUP_CHECK_SERVICE_TEXT
const STARTUP_SERVICE_START_ERROR
const STARTUP_SERVICE_ERROR
const STARTUP_SERVICE_SYNTAX_ERROR
const STARTUP_SERVICE_CREATE_ERROR
const STARTUP_SERVICE_PORT_ERROR
const STARTUP_INSTALL_SERVICE_TEXT
static isPortInUse($port)
static killBins($refreshProcs=false)

References $bearsamppBins, $bearsamppLang, $bearsamppRoot, $port, checkApacheServiceWithTimeout(), checkMySQLServiceWithTimeout(), BinApache\CMD_SYNTAX_CHECK, BinMariadb\CMD_SYNTAX_CHECK, BinMysql\CMD_SYNTAX_CHECK, Util\getMicrotime(), Util\isPortInUse(), Win32Ps\killBins(), Util\logTrace(), BinApache\SERVICE_NAME, BinMailpit\SERVICE_NAME, BinMariadb\SERVICE_NAME, BinMemcached\SERVICE_NAME, BinMysql\SERVICE_NAME, BinPostgresql\SERVICE_NAME, BinXlight\SERVICE_NAME, Lang\STARTUP_CHECK_SERVICE_TEXT, Lang\STARTUP_INSTALL_SERVICE_TEXT, Lang\STARTUP_SERVICE_CREATE_ERROR, Lang\STARTUP_SERVICE_ERROR, Lang\STARTUP_SERVICE_PORT_ERROR, Lang\STARTUP_SERVICE_START_ERROR, Lang\STARTUP_SERVICE_SYNTAX_ERROR, Lang\STARTUP_START_SERVICE_TEXT, Win32Service\VBS_PATH_NAME, and writeLog().

Referenced by processWindow().

◆ killOldInstances()

killOldInstances ( )
private

Kills old instances of Bearsampp processes.

Definition at line 512 of file class.action.startup.php.

513 {
514 global $bearsamppLang;
515
516 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_KILL_OLD_PROCS_TEXT ) );
517 $this->splash->incrProgressBar();
518
519 // Stop services
520 /*foreach ($bearsamppBins->getServices() as $sName => $service) {
521 $serviceInfos = $service->infos();
522 if ($serviceInfos === false) {
523 continue;
524 }
525 $service->stop();
526 }*/
527
528 // Stop third party procs
529 $procsKilled = Win32Ps::killBins();
530 if ( !empty( $procsKilled ) ) {
531 $this->writeLog( 'Procs killed:' );
532 $procsKilledSort = array();
533 foreach ( $procsKilled as $proc ) {
535 $procsKilledSort[] = '-> ' . basename( $unixExePath ) . ' (PID ' . $proc[Win32Ps::PROCESS_ID] . ') in ' . $unixExePath;
536 }
537 sort( $procsKilledSort );
538 foreach ( $procsKilledSort as $proc ) {
539 $this->writeLog( $proc );
540 }
541 }
542 }
$proc
Definition ajax.php:43
const STARTUP_KILL_OLD_PROCS_TEXT
static formatUnixPath($path)
const EXECUTABLE_PATH
const PROCESS_ID

References $bearsamppLang, $proc, Win32Ps\EXECUTABLE_PATH, Util\formatUnixPath(), Win32Ps\killBins(), Win32Ps\PROCESS_ID, Lang\STARTUP_KILL_OLD_PROCS_TEXT, and writeLog().

Referenced by processWindow().

◆ processWindow()

processWindow ( $window,
$id,
$ctrl,
$param1,
$param2 )

Processes the main window events during startup.

Parameters
mixed$windowThe window handle.
int$idThe event ID.
mixed$ctrlThe control that triggered the event.
mixed$param1Additional parameter 1.
mixed$param2Additional parameter 2.

Definition at line 73 of file class.action.startup.php.

74 {
75 global $bearsamppRoot, $bearsamppCore, $bearsamppLang, $bearsamppBins, $bearsamppTools, $bearsamppApps, $bearsamppWinbinder;
76
77 Util::logTrace('Starting processWindow method');
78
79 // Rotation logs
80 Util::logTrace('Performing log rotation');
81 $this->rotationLogs();
82
83 // Clean
84 Util::logTrace('Starting cleanup operations');
85 $this->cleanTmpFolders();
86 $this->cleanOldBehaviors();
87
88 // List procs
89 Util::logTrace('Listing running processes');
90 if ($bearsamppRoot->getProcs() !== false) {
91 $this->writeLog('List procs:');
92 $listProcs = array();
93 foreach ($bearsamppRoot->getProcs() as $proc) {
95 $listProcs[] = '-> ' . basename($unixExePath) . ' (PID ' . $proc[Win32Ps::PROCESS_ID] . ') in ' . $unixExePath;
96 }
97 sort($listProcs);
98 foreach ($listProcs as $proc) {
99 $this->writeLog($proc);
100 }
101 Util::logTrace('Found ' . count($listProcs) . ' running processes');
102 } else {
103 Util::logTrace('No processes found or unable to retrieve process list');
104 }
105
106 // List modules
107 Util::logTrace('Listing bins modules');
108 $this->writeLog('List bins modules:');
109 foreach ($bearsamppBins->getAll() as $module) {
110 if (!$module->isEnable()) {
111 $this->writeLog('-> ' . $module->getName() . ': ' . $bearsamppLang->getValue(Lang::DISABLED));
112 Util::logTrace('Bin module ' . $module->getName() . ' is disabled');
113 } else {
114 $this->writeLog('-> ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
115 Util::logTrace('Bin module ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
116 }
117 }
118
119 Util::logTrace('Listing tools modules');
120 $this->writeLog('List tools modules:');
121 foreach ($bearsamppTools->getAll() as $module) {
122 if (!$module->isEnable()) {
123 $this->writeLog('-> ' . $module->getName() . ': ' . $bearsamppLang->getValue(Lang::DISABLED));
124 Util::logTrace('Tool module ' . $module->getName() . ' is disabled');
125 } else {
126 $this->writeLog('-> ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
127 Util::logTrace('Tool module ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
128 }
129 }
130
131 Util::logTrace('Listing apps modules');
132 $this->writeLog('List apps modules:');
133 foreach ($bearsamppApps->getAll() as $module) {
134 if (!$module->isEnable()) {
135 $this->writeLog('-> ' . $module->getName() . ': ' . $bearsamppLang->getValue(Lang::DISABLED));
136 Util::logTrace('App module ' . $module->getName() . ' is disabled');
137 } else {
138 $this->writeLog('-> ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
139 Util::logTrace('App module ' . $module->getName() . ': ' . $module->getVersion() . ' (' . $module->getRelease() . ')');
140 }
141 }
142
143 // Kill old instances
144 Util::logTrace('Killing old instances');
145 $this->killOldInstances();
146
147 // Prepare app
148 Util::logTrace('Preparing application - refreshing hostname');
149 $this->refreshHostname();
150
151 Util::logTrace('Checking launch startup settings');
152 $this->checkLaunchStartup();
153
154 Util::logTrace('Checking browser configuration');
155 $this->checkBrowser();
156
157 Util::logTrace('Gathering system information');
158 $this->sysInfos();
159
160 Util::logTrace('Refreshing aliases');
161 $this->refreshAliases();
162
163 Util::logTrace('Refreshing virtual hosts');
164 $this->refreshVhosts();
165
166 // Check app path
167 Util::logTrace('Checking application path');
168 $this->checkPath();
169
170 Util::logTrace('Scanning folders');
171 $this->scanFolders();
172
173 Util::logTrace('Changing paths in files');
174 $this->changePath();
175
176 Util::logTrace('Saving current path');
177 $this->savePath();
178
179 // Check BEARSAMPP_PATH, BEARSAMPP_BINS and System Path reg keys
180 Util::logTrace('Checking PATH registry key');
181 $this->checkPathRegKey();
182
183 Util::logTrace('Checking BINS registry key');
184 $this->checkBinsRegKey();
185
186 Util::logTrace('Checking System PATH registry key');
187 $this->checkSystemPathRegKey();
188
189 // Update config
190 Util::logTrace('Updating configuration');
191 $this->updateConfig();
192
193 // Create SSL certificates
194 Util::logTrace('Creating SSL certificates');
195 $this->createSslCrts();
196
197 // Install
198 Util::logTrace('Installing services');
199 $this->installServices();
200
201 // Actions if everything OK
202 if (!$this->restart && empty($this->error)) {
203 Util::logTrace('Startup completed successfully - refreshing Git repositories');
204 $this->refreshGitRepos();
205 $startupTime = round(Util::getMicrotime() - $this->startTime, 3);
206 $this->writeLog('Started in ' . $startupTime . 's');
207 Util::logTrace('Application started successfully in ' . $startupTime . ' seconds');
208 } else {
209 Util::logTrace('Startup issues detected - incrementing progress bar');
210 $this->splash->incrProgressBar(2);
211 }
212
213 if ($this->restart) {
214 Util::logTrace('Restart required - preparing to restart application');
215 $this->writeLog(APP_TITLE . ' has to be restarted');
216 $this->splash->setTextLoading(
217 sprintf(
219 APP_TITLE . ' ' . $bearsamppCore->getAppVersion()
220 )
221 );
222
223 Util::logTrace('Deleting all services before restart');
224 foreach ($bearsamppBins->getServices() as $sName => $service) {
225 Util::logTrace('Deleting service: ' . $sName);
226 $service->delete();
227 }
228
229 Util::logTrace('Setting execution action to RESTART');
231 }
232
233 if (!empty($this->error)) {
234 Util::logTrace('Errors occurred during startup: ' . $this->error);
235 $this->writeLog('Error: ' . $this->error);
236 $bearsamppWinbinder->messageBoxError($this->error, $bearsamppLang->getValue(Lang::STARTUP_ERROR_TITLE));
237 }
238
239 Util::logTrace('Starting loading screen');
241 Util::logTrace('Loading process completed');
242
243 // Closing cli to finish startup
244 Util::logTrace('Finishing startup process');
245
246 $currentPid = Win32Ps::getCurrentPid();
247 // Add timeout parameter (15 seconds) to prevent hanging
248 ActionQuit::terminatePhpProcesses($currentPid, null, null, 15);
249
250 // Safely reset WinBinder instead of trying to destroy specific windows
251 $bearsamppWinbinder->reset();
252
253 // Force exit if we're still running after termination attempt
254 Util::logTrace('Forcing exit as final fallback');
255 exit(0);
256
257 }
static terminatePhpProcesses($excludePid, $window=null, $splash=null, $timeout=10)
const DISABLED
const STARTUP_PREPARE_RESTART_TEXT
const STARTUP_ERROR_TITLE
static startLoading()
static getCurrentPid()

References $bearsamppBins, $bearsamppCore, $bearsamppLang, $bearsamppRoot, $proc, APP_TITLE, changePath(), checkBinsRegKey(), checkBrowser(), checkLaunchStartup(), checkPath(), checkPathRegKey(), checkSystemPathRegKey(), cleanOldBehaviors(), cleanTmpFolders(), createSslCrts(), Lang\DISABLED, Win32Ps\EXECUTABLE_PATH, exit, Util\formatUnixPath(), Win32Ps\getCurrentPid(), Util\getMicrotime(), installServices(), killOldInstances(), Util\logTrace(), Win32Ps\PROCESS_ID, refreshAliases(), refreshGitRepos(), refreshHostname(), refreshVhosts(), ActionExec\RESTART, rotationLogs(), savePath(), scanFolders(), Util\startLoading(), Lang\STARTUP_ERROR_TITLE, Lang\STARTUP_PREPARE_RESTART_TEXT, sysInfos(), ActionQuit\terminatePhpProcesses(), updateConfig(), and writeLog().

◆ refreshAliases()

refreshAliases ( )
private

Refreshes the aliases in the Apache configuration.

Definition at line 609 of file class.action.startup.php.

610 {
612
613 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_REFRESH_ALIAS_TEXT ) );
614 $this->splash->incrProgressBar();
615 $this->writeLog( 'Refresh aliases' );
616
617 $bearsamppBins->getApache()->refreshAlias( $bearsamppConfig->isOnline() );
618 }
const STARTUP_REFRESH_ALIAS_TEXT

References $bearsamppBins, $bearsamppConfig, $bearsamppLang, Lang\STARTUP_REFRESH_ALIAS_TEXT, and writeLog().

Referenced by processWindow().

◆ refreshGitRepos()

refreshGitRepos ( )
private

Refreshes Git repositories if the scan on startup is enabled. Logs the number of repositories found.

Definition at line 1109 of file class.action.startup.php.

1110 {
1111 global $bearsamppLang, $bearsamppTools;
1112
1113 $this->splash->incrProgressBar();
1114 if ( $bearsamppTools->getGit()->isScanStartup() ) {
1115 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_REFRESH_GIT_REPOS_TEXT ) );
1116
1117 $repos = $bearsamppTools->getGit()->findRepos( false );
1118 $this->writeLog( 'Update GIT repos: ' . count( $repos ) . ' found' );
1119 }
1120 }
const STARTUP_REFRESH_GIT_REPOS_TEXT

References $bearsamppLang, Lang\STARTUP_REFRESH_GIT_REPOS_TEXT, and writeLog().

Referenced by processWindow().

◆ refreshHostname()

refreshHostname ( )
private

Refreshes the hostname in the configuration.

Definition at line 547 of file class.action.startup.php.

548 {
550
551 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_REFRESH_HOSTNAME_TEXT ) );
552 $this->splash->incrProgressBar();
553 $this->writeLog( 'Refresh hostname' );
554
555 $bearsamppConfig->replace( Config::CFG_HOSTNAME, gethostname() );
556 }
const CFG_HOSTNAME
const STARTUP_REFRESH_HOSTNAME_TEXT

References $bearsamppConfig, $bearsamppLang, Config\CFG_HOSTNAME, Lang\STARTUP_REFRESH_HOSTNAME_TEXT, and writeLog().

Referenced by processWindow().

◆ refreshVhosts()

refreshVhosts ( )
private

Refreshes the virtual hosts in the Apache configuration.

Definition at line 623 of file class.action.startup.php.

624 {
626
627 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_REFRESH_VHOSTS_TEXT ) );
628 $this->splash->incrProgressBar();
629 $this->writeLog( 'Refresh vhosts' );
630
631 $bearsamppBins->getApache()->refreshVhosts( $bearsamppConfig->isOnline() );
632 }
const STARTUP_REFRESH_VHOSTS_TEXT

References $bearsamppBins, $bearsamppConfig, $bearsamppLang, Lang\STARTUP_REFRESH_VHOSTS_TEXT, and writeLog().

Referenced by processWindow().

◆ rotationLogs()

rotationLogs ( )
private

Rotates the logs by archiving old logs and purging old archives. Enhanced with file lock checking to prevent permission denied errors.

Definition at line 263 of file class.action.startup.php.

264 {
266
267 Util::logTrace("Starting log rotation process");
268 $this->splash->setTextLoading($bearsamppLang->getValue(Lang::STARTUP_ROTATION_LOGS_TEXT));
269 $this->splash->incrProgressBar();
270
271 $archivesPath = $bearsamppRoot->getLogsPath() . '/archives';
272 if (!is_dir($archivesPath)) {
273 Util::logTrace("Creating archives directory: " . $archivesPath);
274 mkdir($archivesPath, 0777, true);
275 return;
276 }
277
278 $date = date('Y-m-d-His', time());
279 $archiveLogsPath = $archivesPath . '/' . $date;
280 $archiveScriptsPath = $archiveLogsPath . '/scripts';
281
282 // Create archive folders
283 Util::logTrace("Creating archive directories for current rotation");
284 if (!is_dir($archiveLogsPath)) {
285 Util::logTrace("Creating logs archive directory: " . $archiveLogsPath);
286 mkdir($archiveLogsPath, 0777, true);
287 } else {
288 Util::logTrace("Logs archive directory already exists: " . $archiveLogsPath);
289 }
290
291 if (!is_dir($archiveScriptsPath)) {
292 Util::logTrace("Creating scripts archive directory: " . $archiveScriptsPath);
293 mkdir($archiveScriptsPath, 0777, true);
294 } else {
295 Util::logTrace("Scripts archive directory already exists: " . $archiveScriptsPath);
296 }
297
298 // Count archives
299 Util::logTrace("Counting existing archives");
300 $archives = array();
301 $handle = @opendir($archivesPath);
302 if (!$handle) {
303 Util::logTrace("Failed to open archives directory: " . $archivesPath);
304 return;
305 }
306
307 while (false !== ($file = readdir($handle))) {
308 if ($file == '.' || $file == '..') {
309 continue;
310 }
311 $archives[] = $archivesPath . '/' . $file;
312 }
313 closedir($handle);
314 sort($archives);
315 Util::logTrace("Found " . count($archives) . " existing archives");
316
317 // Remove old archives
318 if (count($archives) > $bearsamppConfig->getMaxLogsArchives()) {
319 $total = count($archives) - $bearsamppConfig->getMaxLogsArchives();
320 Util::logTrace("Removing " . $total . " old archives");
321 for ($i = 0; $i < $total; $i++) {
322 Util::logTrace("Deleting old archive: " . $archives[$i]);
323 Util::deleteFolder($archives[$i]);
324 }
325 }
326
327 // Helper function to check if a file is locked
328 $isFileLocked = function($filePath) {
329 if (!file_exists($filePath)) {
330 return false;
331 }
332
333 $handle = @fopen($filePath, 'r+');
334 if ($handle === false) {
335 Util::logTrace("File appears to be locked: " . $filePath);
336 return true; // File is locked
337 }
338
339 fclose($handle);
340 return false; // File is not locked
341 };
342
343 // Logs
344 Util::logTrace("Archiving log files");
345 $srcPath = $bearsamppRoot->getLogsPath();
346 $handle = @opendir($srcPath);
347 if (!$handle) {
348 Util::logTrace("Failed to open logs directory: " . $srcPath);
349 return;
350 }
351
352 $logsCopied = 0;
353 $logsSkipped = 0;
354
355 while (false !== ($file = readdir($handle))) {
356 if ($file == '.' || $file == '..' || is_dir($srcPath . '/' . $file)) {
357 continue;
358 }
359
360 $sourceFile = $srcPath . '/' . $file;
361 $destFile = $archiveLogsPath . '/' . $file;
362
363 // Check if file is locked before attempting to copy
364 if ($isFileLocked($sourceFile)) {
365 Util::logTrace("Skipping locked log file: " . $file);
366 $logsSkipped++;
367 continue;
368 }
369
370 try {
371 if (copy($sourceFile, $destFile)) {
372 $logsCopied++;
373 Util::logTrace("Archived log file: " . $file);
374 } else {
375 $logsSkipped++;
376 Util::logTrace("Failed to copy log file: " . $file);
377 }
378 } catch (Exception $e) {
379 $logsSkipped++;
380 Util::logTrace("Exception copying log file " . $file . ": " . $e->getMessage());
381 }
382 }
383 closedir($handle);
384 Util::logTrace("Logs archived: " . $logsCopied . " copied, " . $logsSkipped . " skipped");
385
386 // Scripts
387 Util::logTrace("Archiving script files");
388 $srcPath = $bearsamppCore->getTmpPath();
389 $handle = @opendir($srcPath);
390 if (!$handle) {
391 Util::logTrace("Failed to open tmp directory: " . $srcPath);
392 return;
393 }
394
395 $scriptsCopied = 0;
396 $scriptsSkipped = 0;
397
398 while (false !== ($file = readdir($handle))) {
399 if ($file == '.' || $file == '..' || is_dir($srcPath . '/' . $file)) {
400 continue;
401 }
402
403 $sourceFile = $srcPath . '/' . $file;
404 $destFile = $archiveScriptsPath . '/' . $file;
405
406 // Check if file is locked before attempting to copy
407 if ($isFileLocked($sourceFile)) {
408 Util::logTrace("Skipping locked script file: " . $file);
409 $scriptsSkipped++;
410 continue;
411 }
412
413 try {
414 if (copy($sourceFile, $destFile)) {
415 $scriptsCopied++;
416 Util::logTrace("Archived script file: " . $file);
417 } else {
418 $scriptsSkipped++;
419 Util::logTrace("Failed to copy script file: " . $file);
420 }
421 } catch (Exception $e) {
422 $scriptsSkipped++;
423 Util::logTrace("Exception copying script file " . $file . ": " . $e->getMessage());
424 }
425 }
426 closedir($handle);
427 Util::logTrace("Scripts archived: " . $scriptsCopied . " copied, " . $scriptsSkipped . " skipped");
428
429 // Purge logs - only delete files that aren't locked
430 Util::logTrace("Purging log files");
431 $logsPath = $bearsamppRoot->getLogsPath();
432 $handle = @opendir($logsPath);
433 if (!$handle) {
434 Util::logTrace("Failed to open logs directory for purging: " . $logsPath);
435 return;
436 }
437
438 $logsDeleted = 0;
439 $logsPurgeSkipped = 0;
440
441 while (false !== ($file = readdir($handle))) {
442 if ($file == '.' || $file == '..' || $file == 'archives' || $file == '.gitignore' || is_dir($logsPath . '/' . $file)) {
443 continue;
444 }
445
446 $filePath = $logsPath . '/' . $file;
447
448 // Check if file is locked before attempting to delete
449 if ($isFileLocked($filePath)) {
450 Util::logTrace("Skipping locked log file during purge: " . $file);
451 $logsPurgeSkipped++;
452 continue;
453 }
454
455 try {
456 if (unlink($filePath)) {
457 $logsDeleted++;
458 Util::logTrace("Purged log file: " . $file);
459 } else {
460 $logsPurgeSkipped++;
461 Util::logTrace("Failed to purge log file: " . $file);
462 }
463 } catch (Exception $e) {
464 $logsPurgeSkipped++;
465 Util::logTrace("Exception purging log file " . $file . ": " . $e->getMessage());
466 }
467 }
468 closedir($handle);
469 Util::logTrace("Logs purged: " . $logsDeleted . " deleted, " . $logsPurgeSkipped . " skipped");
470
471 Util::logTrace("Log rotation completed");
472 }
const STARTUP_ROTATION_LOGS_TEXT
static deleteFolder($path)

References $bearsamppBins, $bearsamppConfig, $bearsamppCore, $bearsamppLang, $bearsamppRoot, Util\deleteFolder(), Util\logTrace(), and Lang\STARTUP_ROTATION_LOGS_TEXT.

Referenced by processWindow().

◆ savePath()

savePath ( )
private

Saves the current application path.

Definition at line 679 of file class.action.startup.php.

680 {
681 global $bearsamppCore;
682
683 file_put_contents( $bearsamppCore->getLastPath(), $this->rootPath );
684 $this->writeLog( 'Save current path: ' . $this->rootPath );
685 }

References $bearsamppCore, and writeLog().

Referenced by processWindow().

◆ scanFolders()

scanFolders ( )
private

Scans folders and logs the number of files to scan.

Definition at line 650 of file class.action.startup.php.

651 {
652 global $bearsamppLang;
653
654 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_SCAN_FOLDERS_TEXT ) );
655 $this->splash->incrProgressBar();
656
657 $this->filesToScan = Util::getFilesToScan();
658 $this->writeLog( 'Files to scan: ' . count( $this->filesToScan ) );
659 }
const STARTUP_SCAN_FOLDERS_TEXT
static getFilesToScan($path=null)

References $bearsamppLang, Util\getFilesToScan(), Lang\STARTUP_SCAN_FOLDERS_TEXT, and writeLog().

Referenced by processWindow().

◆ sysInfos()

sysInfos ( )
private

Logs system information.

Definition at line 595 of file class.action.startup.php.

596 {
597 global $bearsamppLang;
598
599 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_SYS_INFOS ) );
600 $this->splash->incrProgressBar();
601
602 $os = Batch::getOsInfo();
603 $this->writeLog( sprintf( 'OS: %s', $os ) );
604 }
static getOsInfo()
const STARTUP_SYS_INFOS

References $bearsamppLang, Batch\getOsInfo(), Lang\STARTUP_SYS_INFOS, and writeLog().

Referenced by processWindow().

◆ updateConfig()

updateConfig ( )
private

Updates the configuration for bins, tools, and apps. Logs the update process.

Definition at line 795 of file class.action.startup.php.

796 {
797 global $bearsamppLang, $bearsamppBins, $bearsamppTools, $bearsamppApps;
798
799 $this->splash->setTextLoading( $bearsamppLang->getValue( Lang::STARTUP_UPDATE_CONFIG_TEXT ) );
800 $this->splash->incrProgressBar();
801 $this->writeLog( 'Update config' );
802
803 $bearsamppBins->update();
804 $bearsamppTools->update();
805 $bearsamppApps->update();
806 }
const STARTUP_UPDATE_CONFIG_TEXT

References $bearsamppBins, $bearsamppLang, Lang\STARTUP_UPDATE_CONFIG_TEXT, and writeLog().

Referenced by processWindow().

◆ writeLog()

writeLog ( $log)
private

Writes a log message to the startup log file.

Parameters
string$logThe log message to write.

Definition at line 1223 of file class.action.startup.php.

1224 {
1225 global $bearsamppRoot;
1226 Util::logDebug( $log, $bearsamppRoot->getStartupLogFilePath() );
1227 }
static logDebug($data, $file=null)

References $bearsamppRoot, and Util\logDebug().

Referenced by __construct(), changePath(), checkBinsRegKey(), checkBrowser(), checkLaunchStartup(), checkPath(), checkPathRegKey(), checkSystemPathRegKey(), cleanOldBehaviors(), cleanTmpFolders(), installServices(), killOldInstances(), processWindow(), refreshAliases(), refreshGitRepos(), refreshHostname(), refreshVhosts(), savePath(), scanFolders(), sysInfos(), and updateConfig().

Field Documentation

◆ $error

$error
private

Definition at line 21 of file class.action.startup.php.

◆ $filesToScan

$filesToScan
private

Definition at line 24 of file class.action.startup.php.

◆ $restart

$restart
private

Definition at line 19 of file class.action.startup.php.

◆ $rootPath

$rootPath
private

Definition at line 23 of file class.action.startup.php.

◆ $splash

$splash
private

Definition at line 18 of file class.action.startup.php.

◆ $startTime

$startTime
private

Definition at line 20 of file class.action.startup.php.

Referenced by checkApacheServiceWithTimeout().

◆ GAUGE_OTHERS

const GAUGE_OTHERS = 19

Definition at line 27 of file class.action.startup.php.

◆ GAUGE_SERVICES

const GAUGE_SERVICES = 5

Definition at line 26 of file class.action.startup.php.


The documentation for this class was generated from the following file: