From 690692050b14ac33e2c987b01c3a53fd4e84cc77 Mon Sep 17 00:00:00 2001 From: Bear Date: Tue, 17 Dec 2024 20:13:16 -0600 Subject: [PATCH] Refactor core classes with improved type declarations and error handling The commit improves type safety and error handling across core classes: - Add strict type declarations and return types to methods - Improve error handling with try/catch blocks - Refactor class properties with proper visibility and type hints - Add namespace declarations and use statements - Optimize process handling and file operations - Improve code organization and documentation - Remove redundant code and simplify control structures --- core/classes/class.vbs.php | 369 ++++++++--------- core/classes/class.win32ps.php | 130 +++--- core/classes/class.win32service.php | 525 ++++++++++++------------ core/classes/class.winbinder.php | 592 +++++++++++++++------------- 4 files changed, 829 insertions(+), 787 deletions(-) diff --git a/core/classes/class.vbs.php b/core/classes/class.vbs.php index adb23a4bf..9c2379aa9 100644 --- a/core/classes/class.vbs.php +++ b/core/classes/class.vbs.php @@ -1,4 +1,5 @@ getVbsLogFilePath() ); + Util::logDebug($log, $bearsamppRoot->getVbsLogFilePath()); } /** * Counts the number of files and folders in the specified path. * - * @param string $path The path to count files and folders in. - * + * @param string $path The path to count files and folders in. * @return int|false The count of files and folders, or false on failure. */ - public static function countFilesFolders($path) + public static function countFilesFolders(string $path) { - $basename = 'countFilesFolders'; - $resultFile = self::getResultFile( $basename ); + $basename = 'countFilesFolders'; + $resultFile = self::getResultFile($basename); $content = 'Dim objFso, objResultFile, objCheckFile' . PHP_EOL . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objResultFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL; $content .= 'count = 0' . PHP_EOL; $content .= 'CountFiles("' . $path . '")' . PHP_EOL . PHP_EOL; - $content .= 'Function CountFiles(ByVal path)' . PHP_EOL; + $content .= 'Sub CountFiles(ByVal path)' . PHP_EOL; $content .= ' Dim parentFld, subFld' . PHP_EOL; $content .= ' Set parentFld = objFso.GetFolder(path)' . PHP_EOL . PHP_EOL; $content .= ' count = count + parentFld.Files.Count + parentFld.SubFolders.Count' . PHP_EOL; $content .= ' For Each subFld In parentFld.SubFolders' . PHP_EOL; - $content .= ' count = count + CountFiles(subFld.Path)' . PHP_EOL; - $content .= ' Next' . PHP_EOL . PHP_EOL; - $content .= 'End Function' . PHP_EOL . PHP_EOL; + $content .= ' CountFiles(subFld.Path)' . PHP_EOL; + $content .= ' Next' . PHP_EOL; + $content .= 'End Sub' . PHP_EOL . PHP_EOL; $content .= 'objResultFile.Write count' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); + $result = self::exec($basename, $resultFile, $content); - return isset( $result[0] ) && is_numeric( $result[0] ) ? intval( $result[0] ) : false; + return isset($result[0]) && is_numeric($result[0]) ? intval($result[0]) : false; } /** @@ -79,8 +92,8 @@ public static function countFilesFolders($path) */ public static function getDefaultBrowser() { - $basename = 'getDefaultBrowser'; - $resultFile = self::getResultFile( $basename ); + $basename = 'getDefaultBrowser'; + $resultFile = self::getResultFile($basename); $content = 'On Error Resume Next' . PHP_EOL; $content .= 'Err.Clear' . PHP_EOL . PHP_EOL; @@ -88,19 +101,17 @@ public static function getDefaultBrowser() $content .= 'Set objShell = WScript.CreateObject("WScript.Shell")' . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL . PHP_EOL; - $content .= 'objFile.Write objShell.RegRead("HKLM\SOFTWARE\Classes\http\shell\open\command\")' . PHP_EOL; + $content .= 'objFile.Write objShell.RegRead("HKLM\\SOFTWARE\\Classes\\http\\shell\\open\\command\\")' . PHP_EOL; $content .= 'objFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( $result !== false && !empty( $result ) ) { - if ( preg_match( '/"([^"]+)"/', $result[0], $matches ) ) { + $result = self::exec($basename, $resultFile, $content); + if ($result !== false && !empty($result)) { + if (preg_match('/"([^"]+)"/', $result[0], $matches)) { return $matches[1]; + } else { + return str_replace('"', '', $result[0]); } - else { - return str_replace( '"', '', $result[0] ); - } - } - else { + } else { return false; } } @@ -112,8 +123,8 @@ public static function getDefaultBrowser() */ public static function getInstalledBrowsers() { - $basename = 'getInstalledBrowsers'; - $resultFile = self::getResultFile( $basename ); + $basename = 'getInstalledBrowsers'; + $resultFile = self::getResultFile($basename); $content = 'On Error Resume Next' . PHP_EOL; $content .= 'Err.Clear' . PHP_EOL . PHP_EOL; @@ -122,12 +133,12 @@ public static function getInstalledBrowsers() $content .= 'Set objRegistry = GetObject("winmgmts://./root/default:StdRegProv")' . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL . PHP_EOL; - $content .= 'mainKey = "SOFTWARE\WOW6432Node\Clients\StartMenuInternet"' . PHP_EOL; - $content .= 'checkKey = objShell.RegRead("HKLM\" & mainKey & "\")' . PHP_EOL; + $content .= 'mainKey = "SOFTWARE\\WOW6432Node\\Clients\\StartMenuInternet"' . PHP_EOL; + $content .= 'checkKey = objShell.RegRead("HKLM\\" & mainKey & "\\")' . PHP_EOL; $content .= 'If Err.Number <> 0 Then' . PHP_EOL; $content .= ' Err.Clear' . PHP_EOL; - $content .= ' mainKey = "SOFTWARE\Clients\StartMenuInternet"' . PHP_EOL; - $content .= ' checkKey = objShell.RegRead("HKLM\" & mainKey & "\")' . PHP_EOL; + $content .= ' mainKey = "SOFTWARE\\Clients\\StartMenuInternet"' . PHP_EOL; + $content .= ' checkKey = objShell.RegRead("HKLM\\" & mainKey & "\\")' . PHP_EOL; $content .= ' If Err.Number <> 0 Then' . PHP_EOL; $content .= ' mainKey = ""' . PHP_EOL; $content .= ' End If' . PHP_EOL; @@ -136,73 +147,75 @@ public static function getInstalledBrowsers() $content .= 'If mainKey <> "" Then' . PHP_EOL; $content .= ' objRegistry.EnumKey &H80000002, mainKey, arrSubKeys' . PHP_EOL; $content .= ' For Each subKey In arrSubKeys' . PHP_EOL; - $content .= ' objFile.Write objShell.RegRead("HKLM\SOFTWARE\Clients\StartMenuInternet\" & subKey & "\shell\open\command\") & vbCrLf' . PHP_EOL; + $content .= ' objFile.Write objShell.RegRead("HKLM\\SOFTWARE\\Clients\\StartMenuInternet\\" & subKey & "\\shell\\open\\command\\") & vbCrLf' . PHP_EOL; $content .= ' Next' . PHP_EOL; $content .= 'End If' . PHP_EOL; $content .= 'objFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( $result !== false && !empty( $result ) ) { - $rebuildResult = array(); - foreach ( $result as $browser ) { - $rebuildResult[] = str_replace( '"', '', $browser ); + $result = self::exec($basename, $resultFile, $content); + if ($result !== false && !empty($result)) { + $rebuildResult = []; + foreach ($result as $browser) { + $rebuildResult[] = str_replace('"', '', $browser); } - $result = $rebuildResult; + return $rebuildResult; } - return $result; + return false; } /** * Retrieves a list of running processes with specified keys. * - * @param array $vbsKeys The keys to retrieve for each process. - * + * @param array $vbsKeys The keys to retrieve for each process. * @return array|false An array of process information, or false on failure. */ - public static function getListProcs($vbsKeys) + public static function getListProcs(array $vbsKeys) { - $basename = 'getListProcs'; - $resultFile = self::getResultFile( $basename ); - $sep = ' & "' . self::STR_SEPARATOR . '" & _'; + $basename = 'getListProcs'; + $resultFile = self::getResultFile($basename); + $sep = ' & "' . self::STR_SEPARATOR . '" & _'; $content = 'Dim objFso, objResultFile, objWMIService' . PHP_EOL . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objResultFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL; $content .= 'strComputer = "."' . PHP_EOL; - $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\root\cimv2")' . PHP_EOL; + $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\\root\\cimv2")' . PHP_EOL; $content .= 'Set listProcess = objWMIService.ExecQuery ("SELECT * FROM Win32_Process")' . PHP_EOL; $content .= 'For Each process in listProcess' . PHP_EOL; $content .= ' objResultFile.WriteLine(_' . PHP_EOL; - foreach ( $vbsKeys as $vbsKey ) { + foreach ($vbsKeys as $vbsKey) { $content .= ' process.' . $vbsKey . $sep . PHP_EOL; } - $content = substr( $content, 0, strlen( $content ) - strlen( $sep ) - 1 ) . ')' . PHP_EOL; + $content = substr($content, 0, -strlen($sep) - 1) . ')' . PHP_EOL; $content .= 'Next' . PHP_EOL; $content .= 'objResultFile.WriteLine("' . self::END_PROCESS_STR . '")' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; $content .= 'Err.Clear' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( empty( $result ) ) { + $result = self::exec($basename, $resultFile, $content); + if (empty($result)) { return false; } - unset( $result[array_search( self::END_PROCESS_STR, $result )] ); - if ( is_array( $result ) && count( $result ) > 0 ) { - $rebuildResult = array(); - foreach ( $result as $row ) { - $row = explode( trim( self::STR_SEPARATOR ), $row ); - if ( count( $row ) != count( $vbsKeys ) ) { + $result = array_filter($result, function ($line) { + return trim($line) !== self::END_PROCESS_STR; + }); + + if (is_array($result) && count($result) > 0) { + $rebuildResult = []; + foreach ($result as $row) { + $row = explode(trim(self::STR_SEPARATOR), $row); + if (count($row) !== count($vbsKeys)) { continue; } - $processInfo = array(); - foreach ( $vbsKeys as $key => $vbsKey ) { - $processInfo[$vbsKey] = trim( $row[$key] ); + $processInfo = []; + foreach ($vbsKeys as $key => $vbsKey) { + $processInfo[$vbsKey] = trim($row[$key]); } - if ( !empty( $processInfo[Win32Ps::EXECUTABLE_PATH] ) ) { + if (!empty($processInfo[Win32Ps::EXECUTABLE_PATH])) { $rebuildResult[] = $processInfo; } } @@ -216,21 +229,20 @@ public static function getListProcs($vbsKeys) /** * Terminates a process by its PID. * - * @param int $pid The process ID to terminate. - * + * @param int $pid The process ID to terminate. * @return bool True on success, false on failure. */ - public static function killProc($pid) + public static function killProc(int $pid): bool { - $basename = 'killProc'; - $resultFile = self::getResultFile( $basename ); + $basename = 'killProc'; + $resultFile = self::getResultFile($basename); $content = 'Dim objFso, objResultFile, objWMIService' . PHP_EOL . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objResultFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL; $content .= 'strComputer = "."' . PHP_EOL; $content .= 'strProcessKill = "' . $pid . '"' . PHP_EOL; - $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\root\cimv2")' . PHP_EOL; + $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\\root\\cimv2")' . PHP_EOL; $content .= 'Set listProcess = objWMIService.ExecQuery ("Select * from Win32_Process Where ProcessID = " & strProcessKill)' . PHP_EOL; $content .= 'For Each objProcess in listProcess' . PHP_EOL; $content .= ' objResultFile.WriteLine(objProcess.Name & "' . self::STR_SEPARATOR . '" & objProcess.ProcessID & "' . self::STR_SEPARATOR . '" & objProcess.ExecutablePath)' . PHP_EOL; @@ -238,16 +250,16 @@ public static function killProc($pid) $content .= 'Next' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( empty( $result ) ) { + $result = self::exec($basename, $resultFile, $content); + if (empty($result)) { return true; } - if ( is_array( $result ) && count( $result ) > 0 ) { - foreach ( $result as $row ) { - $row = explode( self::STR_SEPARATOR, $row ); - if ( count( $row ) == 3 && !empty( $row[2] ) ) { - Util::logDebug( 'Kill process ' . $row[2] . ' (PID ' . $row[1] . ')' ); + if (is_array($result) && count($result) > 0) { + foreach ($result as $row) { + $row = explode(self::STR_SEPARATOR, $row); + if (count($row) === 3 && !empty($row[2])) { + Util::logDebug('Kill process ' . $row[2] . ' (PID ' . $row[1] . ')'); } } } @@ -258,14 +270,13 @@ public static function killProc($pid) /** * Retrieves a special folder path. * - * @param string $path The VBScript path constant for the special folder. - * + * @param string $path The VBScript path constant for the special folder. * @return string|null The path to the special folder, or null on failure. */ - private static function getSpecialPath($path) + private static function getSpecialPath(string $path): ?string { - $basename = 'getSpecialPath'; - $resultFile = self::getResultFile( $basename ); + $basename = 'getSpecialPath'; + $resultFile = self::getResultFile($basename); $content = 'Dim objShell, objFso, objResultFile' . PHP_EOL . PHP_EOL; $content .= 'Set objShell = Wscript.CreateObject("Wscript.Shell")' . PHP_EOL; @@ -274,9 +285,9 @@ private static function getSpecialPath($path) $content .= 'objResultFile.WriteLine(' . $path . ')' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( !empty( $result ) && is_array( $result ) && count( $result ) == 1 ) { - return Util::formatUnixPath( $result[0] ); + $result = self::exec($basename, $resultFile, $content); + if (!empty($result) && is_array($result) && count($result) === 1) { + return Util::formatUnixPath($result[0]); } return null; @@ -285,50 +296,51 @@ private static function getSpecialPath($path) /** * Retrieves the startup path, optionally appending a file name. * - * @param string|null $file The file name to append to the startup path. - * - * @return string The startup path. + * @param string|null $file The file name to append to the startup path. + * @return string|null The startup path, or null on failure. */ - public static function getStartupPath($file = null) + public static function getStartupPath(?string $file = null): ?string { - return self::getSpecialPath( self::STARTUP_PATH ) . ($file != null ? '/' . $file : ''); + $path = self::getSpecialPath(self::STARTUP_PATH); + if ($path === null) { + return null; + } + return $file !== null ? $path . '/' . $file : $path; } /** * Creates a shortcut to the Bearsampp executable. * - * @param string $savePath The path to save the shortcut. - * + * @param string $savePath The path to save the shortcut. * @return bool True on success, false on failure. */ - public static function createShortcut($savePath) + public static function createShortcut(string $savePath): bool { global $bearsamppRoot, $bearsamppCore; - $basename = 'createShortcut'; - $resultFile = self::getResultFile( $basename ); - $content = 'Dim objShell, objFso, objResultFile' . PHP_EOL . PHP_EOL; + $basename = 'createShortcut'; + $resultFile = self::getResultFile($basename); + + $content = 'Dim objShell, objFso, objResultFile, objShortcut' . PHP_EOL . PHP_EOL; $content .= 'Set objShell = Wscript.CreateObject("Wscript.Shell")' . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objResultFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL . PHP_EOL; $content .= 'Set objShortcut = objShell.CreateShortcut("' . $savePath . '")' . PHP_EOL; - $content .= 'objShortCut.TargetPath = "' . $bearsamppRoot->getExeFilePath() . '"' . PHP_EOL; - $content .= 'objShortCut.WorkingDirectory = "' . $bearsamppRoot->getRootPath() . '"' . PHP_EOL; - $content .= 'objShortCut.Description = "' . APP_TITLE . ' ' . $bearsamppCore->getAppVersion() . '"' . PHP_EOL; - $content .= 'objShortCut.IconLocation = "' . $bearsamppCore->getResourcesPath() . '/homepage/img/icons/app.ico' . '"' . PHP_EOL; - $content .= 'objShortCut.Save' . PHP_EOL; + $content .= 'objShortcut.TargetPath = "' . $bearsamppRoot->getExeFilePath() . '"' . PHP_EOL; + $content .= 'objShortcut.WorkingDirectory = "' . $bearsamppRoot->getRootPath() . '"' . PHP_EOL; + $content .= 'objShortcut.Description = "' . APP_TITLE . ' ' . $bearsamppCore->getAppVersion() . '"' . PHP_EOL; + $content .= 'objShortcut.IconLocation = "' . $bearsamppCore->getResourcesPath() . '/homepage/img/icons/app.ico' . '"' . PHP_EOL; + $content .= 'objShortcut.Save' . PHP_EOL; $content .= 'If Err.Number <> 0 Then' . PHP_EOL; $content .= ' objResultFile.Write Err.Number & ": " & Err.Description' . PHP_EOL; $content .= 'End If' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( empty( $result ) ) { + $result = self::exec($basename, $resultFile, $content); + if (empty($result)) { return true; - } - elseif ( isset( $result[0] ) ) { - Util::logError( 'createShortcut: ' . $result[0] ); - + } elseif (isset($result[0])) { + Util::logError('createShortcut: ' . $result[0]); return false; } @@ -338,49 +350,51 @@ public static function createShortcut($savePath) /** * Retrieves information about a Windows service. * - * @param string $serviceName The name of the service to retrieve information about. - * + * @param string $serviceName The name of the service to retrieve information about. * @return array|false An array of service information, or false on failure. */ - public static function getServiceInfos($serviceName) + public static function getServiceInfos(string $serviceName) { - $basename = 'getServiceInfos'; - $resultFile = self::getResultFile( $basename ); - $sep = ' & "' . self::STR_SEPARATOR . '" & _'; - $vbsKeys = Win32Service::getVbsKeys(); + $basename = 'getServiceInfos'; + $resultFile = self::getResultFile($basename); + $sep = ' & "' . self::STR_SEPARATOR . '" & _'; + $vbsKeys = Win32Service::getVbsKeys(); $content = 'Dim objFso, objResultFile, objWMIService' . PHP_EOL . PHP_EOL; $content .= 'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL; $content .= 'Set objResultFile = objFso.CreateTextFile("' . $resultFile . '", True)' . PHP_EOL; $content .= 'strComputer = "."' . PHP_EOL; - $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\root\cimv2")' . PHP_EOL; + $content .= 'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\\root\\cimv2")' . PHP_EOL; $content .= 'Set listServices = objWMIService.ExecQuery ("SELECT * FROM Win32_Service WHERE Name=\'' . $serviceName . '\'")' . PHP_EOL; $content .= 'For Each service in listServices' . PHP_EOL; $content .= ' objResultFile.WriteLine(_' . PHP_EOL; - foreach ( $vbsKeys as $vbsKey ) { + foreach ($vbsKeys as $vbsKey) { $content .= ' service.' . $vbsKey . $sep . PHP_EOL; } - $content = substr( $content, 0, strlen( $content ) - strlen( $sep ) - 1 ) . ')' . PHP_EOL; + $content = substr($content, 0, -strlen($sep) - 1) . ')' . PHP_EOL; $content .= 'Next' . PHP_EOL; $content .= 'objResultFile.WriteLine("' . self::END_PROCESS_STR . '")' . PHP_EOL; $content .= 'objResultFile.Close' . PHP_EOL; - $result = self::exec( $basename, $resultFile, $content ); - if ( empty( $result ) ) { + $result = self::exec($basename, $resultFile, $content); + if (empty($result)) { return false; } - unset( $result[array_search( self::END_PROCESS_STR, $result )] ); - if ( is_array( $result ) && count( $result ) == 1 ) { - $rebuildResult = array(); - $row = explode( trim( self::STR_SEPARATOR ), $result[0] ); - if ( count( $row ) != count( $vbsKeys ) ) { + $result = array_filter($result, function ($line) { + return trim($line) !== self::END_PROCESS_STR; + }); + + if (is_array($result) && count($result) === 1) { + $rebuildResult = []; + $row = explode(trim(self::STR_SEPARATOR), $result[0]); + if (count($row) !== count($vbsKeys)) { return false; } - foreach ( $vbsKeys as $key => $vbsKey ) { - $rebuildResult[$vbsKey] = trim( $row[$key] ); + foreach ($vbsKeys as $key => $vbsKey) { + $rebuildResult[$vbsKey] = trim($row[$key]); } return $rebuildResult; @@ -392,52 +406,49 @@ public static function getServiceInfos($serviceName) /** * Generates a temporary file path with a given extension and optional custom name. * - * @param string $ext The file extension for the temporary file. - * @param string|null $customName An optional custom name to include in the file name. - * + * @param string $ext The file extension for the temporary file. + * @param string|null $customName An optional custom name to include in the file name. * @return string The formatted path to the temporary file. */ - public static function getTmpFile($ext, $customName = null) + public static function getTmpFile(string $ext, ?string $customName = null): string { global $bearsamppCore; - return Util::formatWindowsPath( $bearsamppCore->getTmpPath() . '/' . (!empty( $customName ) ? $customName . '-' : '') . Util::random() . $ext ); + $filename = (!empty($customName) ? $customName . '-' : '') . Util::random() . $ext; + return Util::formatWindowsPath($bearsamppCore->getTmpPath() . '/' . $filename); } /** * Retrieves the path for a result file based on a given basename. * - * @param string $basename The base name to use for the result file. - * + * @param string $basename The base name to use for the result file. * @return string The path to the result file. */ - public static function getResultFile($basename) + public static function getResultFile(string $basename): string { - return self::getTmpFile( '.vbs', $basename ); + return self::getTmpFile('.vbs', $basename); } /** * Executes a VBScript file and retrieves the result. * - * @param string $basename The base name for the script and result files. - * @param string $resultFile The path to the result file. - * @param string $content The VBScript content to execute. - * @param int|bool $timeout The timeout duration in seconds, or true for default timeout, or false for no timeout. - * + * @param string $basename The base name for the script and result files. + * @param string $resultFile The path to the result file. + * @param string $content The VBScript content to execute. + * @param int|bool $timeout The timeout duration in seconds, or true for default timeout, or false for no timeout. * @return array|false The result of the script execution as an array of lines, or false on failure. */ - public static function exec($basename, $resultFile, $content, $timeout = true) + public static function exec(string $basename, string $resultFile, string $content, $timeout = true) { global $bearsamppConfig, $bearsamppWinbinder; - $result = false; - $scriptPath = self::getTmpFile( '.vbs', $basename ); - $checkFile = self::getTmpFile( '.tmp', $basename ); - $errFile = self::getTmpFile( '.tmp', $basename ); - $randomVarName = Util::random( 15, false ); - $randomObjErrFile = Util::random( 15, false ); - $randomObjFile = Util::random( 15, false ); - $randomObjFso = Util::random( 15, false ); + $scriptPath = self::getTmpFile('.vbs', $basename); + $checkFile = self::getTmpFile('.tmp', $basename); + $errFile = self::getTmpFile('.tmp', $basename); + $randomVarName = Util::random(15, false); + $randomObjErrFile = Util::random(15, false); + $randomObjFile = Util::random(15, false); + $randomObjFso = Util::random(15, false); // Header $header = 'On Error Resume Next' . PHP_EOL . @@ -456,50 +467,44 @@ public static function exec($basename, $resultFile, $content, $timeout = true) $randomObjErrFile . '.Close' . PHP_EOL; // Process - file_put_contents( $scriptPath, $header . $content . $footer ); - $bearsamppWinbinder->exec( 'wscript.exe', '"' . $scriptPath . '"' ); - - $timeout = is_numeric( $timeout ) ? $timeout : ($timeout === true ? $bearsamppConfig->getScriptsTimeout() : false); - $maxtime = time() + $timeout; - $noTimeout = $timeout === false; - while ( $result === false || empty( $result ) ) { - if ( file_exists( $checkFile ) ) { - $check = file( $checkFile ); - if ( !empty( $check ) && trim( $check[0] ) == self::END_PROCESS_STR ) { - $result = file( $resultFile ); + file_put_contents($scriptPath, $header . $content . $footer); + $bearsamppWinbinder->exec('wscript.exe', '"' . $scriptPath . '"'); + + $timeoutDuration = is_numeric($timeout) ? (int)$timeout : ($timeout === true ? $bearsamppConfig->getScriptsTimeout() : false); + $maxtime = time() + $timeoutDuration; + $noTimeout = $timeoutDuration === false; + $result = false; + + while ($result === false || empty($result)) { + if (file_exists($checkFile)) { + $check = file($checkFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (!empty($check) && trim($check[0]) === self::END_PROCESS_STR) { + $result = file($resultFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); break; } } - if ( $maxtime < time() && !$noTimeout ) { + if (!$noTimeout && time() >= $maxtime) { break; } + usleep(100000); // Sleep for 0.1 seconds to prevent CPU overuse } - $err = file_get_contents( $errFile ); - if ( !empty( $err ) ) { - Util::logError( 'VBS error on ' . $basename . ': ' . $err ); + $err = file_get_contents($errFile); + if (!empty($err)) { + Util::logError('VBS error on ' . $basename . ': ' . $err); } - self::writeLog( 'Exec ' . $basename . ':' ); - self::writeLog( '-> content: ' . str_replace( PHP_EOL, ' \\\\ ', $content ) ); - self::writeLog( '-> errFile: ' . $errFile ); - self::writeLog( '-> checkFile: ' . $checkFile ); - self::writeLog( '-> resultFile: ' . $resultFile ); - self::writeLog( '-> scriptPath: ' . $scriptPath ); - - if ( $result !== false && !empty( $result ) ) { - $rebuildResult = array(); - foreach ( $result as $row ) { - $row = trim( $row ); - if ( !empty( $row ) ) { - $rebuildResult[] = $row; - } - } - $result = $rebuildResult; - self::writeLog( '-> result: ' . substr( implode( ' \\\\ ', $result ), 0, 2048 ) ); - } - else { - self::writeLog( '-> result: N/A' ); + self::writeLog('Exec ' . $basename . ':'); + self::writeLog('-> content: ' . str_replace(PHP_EOL, ' \\\\ ', $content)); + self::writeLog('-> errFile: ' . $errFile); + self::writeLog('-> checkFile: ' . $checkFile); + self::writeLog('-> resultFile: ' . $resultFile); + self::writeLog('-> scriptPath: ' . $scriptPath); + + if ($result !== false && !empty($result)) { + self::writeLog('-> result: ' . substr(implode(' \\\\ ', $result), 0, 2048)); + } else { + self::writeLog('-> result: N/A'); } return $result; diff --git a/core/classes/class.win32ps.php b/core/classes/class.win32ps.php index b195b22a4..4a41ddbc9 100644 --- a/core/classes/class.win32ps.php +++ b/core/classes/class.win32ps.php @@ -1,4 +1,5 @@ $statProc['pid'], - self::EXECUTABLE_PATH => $statProc['exe'] - ); + self::EXECUTABLE_PATH => $statProc['exe'], + ]; } return null; } + /** + * Retrieves a list of running processes. + * + * @return array|null An array of process information, or null on failure. + */ + public static function getListProcs(): ?array + { + return Vbs::getListProcs(self::getKeys()); + } + /** * Checks if a process with the specified PID exists. * * @param int $pid The process ID to check. * @return bool True if the process exists, false otherwise. */ - public static function exists($pid) + public static function exists(int $pid): bool { return self::findByPid($pid) !== false; } @@ -116,13 +126,13 @@ public static function exists($pid) * @param int $pid The process ID to find. * @return array|false An array of process information, or false if not found. */ - public static function findByPid($pid) + public static function findByPid(int $pid): array|false { - if (!empty($pid)) { + if ($pid > 0) { $procs = self::getListProcs(); - if ($procs !== false) { + if ($procs !== null) { foreach ($procs as $proc) { - if ($proc[self::PROCESS_ID] == $pid) { + if (intval($proc[self::PROCESS_ID]) === $pid) { return $proc; } } @@ -138,15 +148,15 @@ public static function findByPid($pid) * @param string $path The path to the executable. * @return array|false An array of process information, or false if not found. */ - public static function findByPath($path) + public static function findByPath(string $path): array|false { $path = Util::formatUnixPath($path); if (!empty($path) && is_file($path)) { $procs = self::getListProcs(); - if ($procs !== false) { + if ($procs !== null) { foreach ($procs as $proc) { - $unixExePath = Util::formatUnixPath($proc[self::EXECUTABLE_PATH]); - if ($unixExePath == $path) { + $unixExePath = Util::formatUnixPath($proc[self::EXECUTABLE_PATH] ?? ''); + if ($unixExePath === $path) { return $proc; } } @@ -160,11 +170,11 @@ public static function findByPath($path) * Terminates a process by its PID. * * @param int $pid The process ID to terminate. + * @return void */ - public static function kill($pid) + public static function kill(int $pid): void { - $pid = intval($pid); - if (!empty($pid)) { + if ($pid > 0) { Vbs::killProc($pid); } } @@ -175,42 +185,46 @@ public static function kill($pid) * @param bool $refreshProcs Whether to refresh the list of processes before terminating. * @return array An array of terminated processes. */ - public static function killBins($refreshProcs = false) + public static function killBins(bool $refreshProcs = false): array { global $bearsamppRoot; - $killed = array(); - $procs = $bearsamppRoot->getProcs(); - if ($refreshProcs) { - $procs = self::getListProcs(); - } + $killed = []; + + $procs = $refreshProcs ? self::getListProcs() : $bearsamppRoot->getProcs(); - if ($procs !== false) { + if ($procs !== null) { foreach ($procs as $proc) { - $unixExePath = Util::formatUnixPath($proc[self::EXECUTABLE_PATH]); - $unixCommandPath = Util::formatUnixPath($proc[self::COMMAND_LINE]); + $unixExePath = Util::formatUnixPath($proc[self::EXECUTABLE_PATH] ?? ''); + $unixCommandPath = Util::formatUnixPath($proc[self::COMMAND_LINE] ?? ''); - // Not kill current PID (PHP) - if ($proc[self::PROCESS_ID] == self::getCurrentPid()) { + // Do not kill current process (PHP) + if (intval($proc[self::PROCESS_ID] ?? 0) === self::getCurrentPid()) { continue; } - // Not kill bearsampp - if ($unixExePath == $bearsamppRoot->getExeFilePath()) { + // Do not kill bearsampp.exe + if ($unixExePath === $bearsamppRoot->getExeFilePath()) { continue; } - // Not kill inside www - if (Util::startWith($unixExePath, $bearsamppRoot->getWwwPath() . '/') || Util::contains($unixCommandPath, $bearsamppRoot->getWwwPath() . '/')) { + // Do not kill processes inside www directory + if ( + Util::startWith($unixExePath, $bearsamppRoot->getWwwPath() . '/') || + Util::contains($unixCommandPath, $bearsamppRoot->getWwwPath() . '/') + ) { continue; } - // Not kill external process - if (!Util::startWith($unixExePath, $bearsamppRoot->getRootPath() . '/') && !Util::contains($unixCommandPath, $bearsamppRoot->getRootPath() . '/')) { + // Do not kill external processes + if ( + !Util::startWith($unixExePath, $bearsamppRoot->getRootPath() . '/') && + !Util::contains($unixCommandPath, $bearsamppRoot->getRootPath() . '/') + ) { continue; } - self::kill($proc[self::PROCESS_ID]); + self::kill(intval($proc[self::PROCESS_ID])); $killed[] = $proc; } } diff --git a/core/classes/class.win32service.php b/core/classes/class.win32service.php index 501beb1dc..a1757a841 100644 --- a/core/classes/class.win32service.php +++ b/core/classes/class.win32service.php @@ -7,6 +7,18 @@ * Github: https://github.com/Bearsampp */ +use Bearsampp\Core\Util; +use Bearsampp\Core\Batch; +use Bearsampp\Core\Bins\BinFilezilla; +use Bearsampp\Core\Bins\BinPostgresql; +use Bearsampp\Core\Bins\BinMysql; +use Bearsampp\Core\Bins\BinMailhog; +use Bearsampp\Core\Bins\BinMailpit; +use Bearsampp\Core\Bins\BinMemcached; +use Bearsampp\Core\Bins\BinXlight; +use Bearsampp\Core\Bins\BinApache; +use Bearsampp\Core\Bins\BinMariadb; + /** * Class Win32Service * @@ -16,94 +28,94 @@ class Win32Service { // Win32Service Service Status Constants - const WIN32_SERVICE_CONTINUE_PENDING = '5'; - const WIN32_SERVICE_PAUSE_PENDING = '6'; - const WIN32_SERVICE_PAUSED = '7'; - const WIN32_SERVICE_RUNNING = '4'; - const WIN32_SERVICE_START_PENDING = '2'; - const WIN32_SERVICE_STOP_PENDING = '3'; - const WIN32_SERVICE_STOPPED = '1'; - const WIN32_SERVICE_NA = '0'; + public const WIN32_SERVICE_CONTINUE_PENDING = '5'; + public const WIN32_SERVICE_PAUSE_PENDING = '6'; + public const WIN32_SERVICE_PAUSED = '7'; + public const WIN32_SERVICE_RUNNING = '4'; + public const WIN32_SERVICE_START_PENDING = '2'; + public const WIN32_SERVICE_STOP_PENDING = '3'; + public const WIN32_SERVICE_STOPPED = '1'; + public const WIN32_SERVICE_NA = '0'; // Win32 Error Codes - const WIN32_ERROR_ACCESS_DENIED = '5'; - const WIN32_ERROR_CIRCULAR_DEPENDENCY = '423'; - const WIN32_ERROR_DATABASE_DOES_NOT_EXIST = '429'; - const WIN32_ERROR_DEPENDENT_SERVICES_RUNNING = '41B'; - const WIN32_ERROR_DUPLICATE_SERVICE_NAME = '436'; - const WIN32_ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = '427'; - const WIN32_ERROR_INSUFFICIENT_BUFFER = '7A'; - const WIN32_ERROR_INVALID_DATA = 'D'; - const WIN32_ERROR_INVALID_HANDLE = '6'; - const WIN32_ERROR_INVALID_LEVEL = '7C'; - const WIN32_ERROR_INVALID_NAME = '7B'; - const WIN32_ERROR_INVALID_PARAMETER = '57'; - const WIN32_ERROR_INVALID_SERVICE_ACCOUNT = '421'; - const WIN32_ERROR_INVALID_SERVICE_CONTROL = '41C'; - const WIN32_ERROR_PATH_NOT_FOUND = '3'; - const WIN32_ERROR_SERVICE_ALREADY_RUNNING = '420'; - const WIN32_ERROR_SERVICE_CANNOT_ACCEPT_CTRL = '425'; - const WIN32_ERROR_SERVICE_DATABASE_LOCKED = '41F'; - const WIN32_ERROR_SERVICE_DEPENDENCY_DELETED = '433'; - const WIN32_ERROR_SERVICE_DEPENDENCY_FAIL = '42C'; - const WIN32_ERROR_SERVICE_DISABLED = '422'; - const WIN32_ERROR_SERVICE_DOES_NOT_EXIST = '424'; - const WIN32_ERROR_SERVICE_EXISTS = '431'; - const WIN32_ERROR_SERVICE_LOGON_FAILED = '42D'; - const WIN32_ERROR_SERVICE_MARKED_FOR_DELETE = '430'; - const WIN32_ERROR_SERVICE_NO_THREAD = '41E'; - const WIN32_ERROR_SERVICE_NOT_ACTIVE = '426'; - const WIN32_ERROR_SERVICE_REQUEST_TIMEOUT = '41D'; - const WIN32_ERROR_SHUTDOWN_IN_PROGRESS = '45B'; - const WIN32_NO_ERROR = '0'; - - const SERVER_ERROR_IGNORE = '0'; - const SERVER_ERROR_NORMAL = '1'; - - const SERVICE_AUTO_START = '2'; - const SERVICE_DEMAND_START = '3'; - const SERVICE_DISABLED = '4'; - - const PENDING_TIMEOUT = 20; - const SLEEP_TIME = 500000; - - const VBS_NAME = 'Name'; - const VBS_DISPLAY_NAME = 'DisplayName'; - const VBS_DESCRIPTION = 'Description'; - const VBS_PATH_NAME = 'PathName'; - const VBS_STATE = 'State'; - - private $name; - private $displayName; - private $binPath; - private $params; - private $startType; - private $errorControl; - private $nssm; - - private $latestStatus; - private $latestError; + public const WIN32_ERROR_ACCESS_DENIED = '5'; + public const WIN32_ERROR_CIRCULAR_DEPENDENCY = '423'; + public const WIN32_ERROR_DATABASE_DOES_NOT_EXIST = '429'; + public const WIN32_ERROR_DEPENDENT_SERVICES_RUNNING = '41B'; + public const WIN32_ERROR_DUPLICATE_SERVICE_NAME = '436'; + public const WIN32_ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = '427'; + public const WIN32_ERROR_INSUFFICIENT_BUFFER = '7A'; + public const WIN32_ERROR_INVALID_DATA = 'D'; + public const WIN32_ERROR_INVALID_HANDLE = '6'; + public const WIN32_ERROR_INVALID_LEVEL = '7C'; + public const WIN32_ERROR_INVALID_NAME = '7B'; + public const WIN32_ERROR_INVALID_PARAMETER = '57'; + public const WIN32_ERROR_INVALID_SERVICE_ACCOUNT = '421'; + public const WIN32_ERROR_INVALID_SERVICE_CONTROL = '41C'; + public const WIN32_ERROR_PATH_NOT_FOUND = '3'; + public const WIN32_ERROR_SERVICE_ALREADY_RUNNING = '420'; + public const WIN32_ERROR_SERVICE_CANNOT_ACCEPT_CTRL = '425'; + public const WIN32_ERROR_SERVICE_DATABASE_LOCKED = '41F'; + public const WIN32_ERROR_SERVICE_DEPENDENCY_DELETED = '433'; + public const WIN32_ERROR_SERVICE_DEPENDENCY_FAIL = '42C'; + public const WIN32_ERROR_SERVICE_DISABLED = '422'; + public const WIN32_ERROR_SERVICE_DOES_NOT_EXIST = '424'; + public const WIN32_ERROR_SERVICE_EXISTS = '431'; + public const WIN32_ERROR_SERVICE_LOGON_FAILED = '42D'; + public const WIN32_ERROR_SERVICE_MARKED_FOR_DELETE = '430'; + public const WIN32_ERROR_SERVICE_NO_THREAD = '41E'; + public const WIN32_ERROR_SERVICE_NOT_ACTIVE = '426'; + public const WIN32_ERROR_SERVICE_REQUEST_TIMEOUT = '41D'; + public const WIN32_ERROR_SHUTDOWN_IN_PROGRESS = '45B'; + public const WIN32_NO_ERROR = '0'; + + public const SERVER_ERROR_IGNORE = '0'; + public const SERVER_ERROR_NORMAL = '1'; + + public const SERVICE_AUTO_START = '2'; + public const SERVICE_DEMAND_START = '3'; + public const SERVICE_DISABLED = '4'; + + public const PENDING_TIMEOUT = 20; + public const SLEEP_TIME = 500000; + + public const VBS_NAME = 'Name'; + public const VBS_DISPLAY_NAME = 'DisplayName'; + public const VBS_DESCRIPTION = 'Description'; + public const VBS_PATH_NAME = 'PathName'; + public const VBS_STATE = 'State'; + + private string $name; + private string $displayName; + private string $binPath; + private string $params; + private string $startType; + private string $errorControl; + private ?Nssm $nssm = null; + + private string $latestStatus; + private string $latestError; /** * Constructor for the Win32Service class. * - * @param string $name The name of the service. + * @param string $name The name of the service. */ - public function __construct($name) + public function __construct(string $name) { - Util::logInitClass( $this ); + Util::logInitClass($this); $this->name = $name; } /** * Writes a log entry. * - * @param string $log The log message. + * @param string $log The log message. */ - private function writeLog($log) + private function writeLog(string $log): void { global $bearsamppRoot; - Util::logDebug( $log, $bearsamppRoot->getServicesLogFilePath() ); + Util::logDebug($log, $bearsamppRoot->getServicesLogFilePath()); } /** @@ -111,33 +123,33 @@ private function writeLog($log) * * @return array The array of VBS keys. */ - public static function getVbsKeys() + public static function getVbsKeys(): array { - return array( + return [ self::VBS_NAME, self::VBS_DISPLAY_NAME, self::VBS_DESCRIPTION, self::VBS_PATH_NAME, self::VBS_STATE - ); + ]; } /** * Calls a Win32 service function. * - * @param string $function The function name. - * @param mixed $param The parameter to pass to the function. - * @param bool $checkError Whether to check for errors. + * @param string $function The function name. + * @param mixed $param The parameter to pass to the function. + * @param bool $checkError Whether to check for errors. * * @return mixed The result of the function call. */ - private function callWin32Service($function, $param, $checkError = false) + private function callWin32Service(string $function, mixed $param, bool $checkError = false): mixed { $result = false; - if ( function_exists( $function ) ) { - $result = call_user_func( $function, $param ); - if ( $checkError && dechex( $result ) != self::WIN32_NO_ERROR ) { - $this->latestError = dechex( $result ); + if (function_exists($function)) { + $result = call_user_func($function, $param); + if ($checkError && dechex($result) != self::WIN32_NO_ERROR) { + $this->latestError = dechex($result); } } @@ -147,32 +159,31 @@ private function callWin32Service($function, $param, $checkError = false) /** * Queries the status of the service. * - * @param bool $timeout Whether to use a timeout. + * @param bool $timeout Whether to use a timeout. * * @return string The status of the service. */ - public function status($timeout = true) + public function status(bool $timeout = true): string { - usleep( self::SLEEP_TIME ); + usleep(self::SLEEP_TIME); $this->latestStatus = self::WIN32_SERVICE_NA; - $maxtime = time() + self::PENDING_TIMEOUT; - - while ( $this->latestStatus == self::WIN32_SERVICE_NA || $this->isPending( $this->latestStatus ) ) { - $this->latestStatus = $this->callWin32Service( 'win32_query_service_status', $this->getName() ); - if ( is_array( $this->latestStatus ) && isset( $this->latestStatus['CurrentState'] ) ) { - $this->latestStatus = dechex( $this->latestStatus['CurrentState'] ); - } - elseif ( dechex( $this->latestStatus ) == self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST ) { - $this->latestStatus = dechex( $this->latestStatus ); + $maxtime = time() + self::PENDING_TIMEOUT; + + while ($this->latestStatus == self::WIN32_SERVICE_NA || $this->isPending($this->latestStatus)) { + $this->latestStatus = $this->callWin32Service('win32_query_service_status', $this->getName()); + if (is_array($this->latestStatus) && isset($this->latestStatus['CurrentState'])) { + $this->latestStatus = dechex($this->latestStatus['CurrentState']); + } elseif (dechex($this->latestStatus) == self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST) { + $this->latestStatus = dechex($this->latestStatus); } - if ( $timeout && $maxtime < time() ) { + if ($timeout && $maxtime < time()) { break; } } - if ( $this->latestStatus == self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST ) { - $this->latestError = $this->latestStatus; + if ($this->latestStatus == self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST) { + $this->latestError = $this->latestStatus; $this->latestStatus = self::WIN32_SERVICE_NA; } @@ -184,56 +195,54 @@ public function status($timeout = true) * * @return bool True if the service was created successfully, false otherwise. */ - public function create() + public function create(): bool { global $bearsamppBins; - if ( $this->getName() == BinFilezilla::SERVICE_NAME ) { + if ($this->getName() == BinFilezilla::SERVICE_NAME) { $bearsamppBins->getFilezilla()->rebuildConf(); return Batch::installFilezillaService(); - } - elseif ( $this->getName() == BinPostgresql::SERVICE_NAME ) { + } elseif ($this->getName() == BinPostgresql::SERVICE_NAME) { $bearsamppBins->getPostgresql()->rebuildConf(); $bearsamppBins->getPostgresql()->initData(); return Batch::installPostgresqlService(); } - if ( $this->getNssm() instanceof Nssm ) { - $nssmEnvPath = Util::getAppBinsRegKey( false ); + if ($this->getNssm() instanceof Nssm) { + $nssmEnvPath = Util::getAppBinsRegKey(false); $nssmEnvPath .= Util::getNssmEnvPaths(); $nssmEnvPath .= '%SystemRoot%/system32;'; $nssmEnvPath .= '%SystemRoot%;'; $nssmEnvPath .= '%SystemRoot%/system32/Wbem;'; $nssmEnvPath .= '%SystemRoot%/system32/WindowsPowerShell/v1.0'; - $this->getNssm()->setEnvironmentExtra( 'PATH=' . $nssmEnvPath ); + $this->getNssm()->setEnvironmentExtra('PATH=' . $nssmEnvPath); return $this->getNssm()->create(); } - $create = dechex( $this->callWin32Service( 'win32_create_service', array( - 'service' => $this->getName(), - 'display' => $this->getDisplayName(), - 'description' => $this->getDisplayName(), - 'path' => $this->getBinPath(), - 'params' => $this->getParams(), - 'start_type' => $this->getStartType() != null ? $this->getStartType() : self::SERVICE_DEMAND_START, + $create = dechex($this->callWin32Service('win32_create_service', [ + 'service' => $this->getName(), + 'display' => $this->getDisplayName(), + 'description' => $this->getDisplayName(), + 'path' => $this->getBinPath(), + 'params' => $this->getParams(), + 'start_type' => $this->getStartType() != null ? $this->getStartType() : self::SERVICE_DEMAND_START, 'error_control' => $this->getErrorControl() != null ? $this->getErrorControl() : self::SERVER_ERROR_NORMAL, - ), true ) ); - - $this->writeLog( 'Create service: ' . $create . ' (status: ' . $this->status() . ')' ); - $this->writeLog( '-> service: ' . $this->getName() ); - $this->writeLog( '-> display: ' . $this->getDisplayName() ); - $this->writeLog( '-> description: ' . $this->getDisplayName() ); - $this->writeLog( '-> path: ' . $this->getBinPath() ); - $this->writeLog( '-> params: ' . $this->getParams() ); - $this->writeLog( '-> start_type: ' . ($this->getStartType() != null ? $this->getStartType() : self::SERVICE_DEMAND_START) ); - $this->writeLog( '-> service: ' . ($this->getErrorControl() != null ? $this->getErrorControl() : self::SERVER_ERROR_NORMAL) ); - - if ( $create != self::WIN32_NO_ERROR ) { + ], true)); + + $this->writeLog('Create service: ' . $create . ' (status: ' . $this->status() . ')'); + $this->writeLog('-> service: ' . $this->getName()); + $this->writeLog('-> display: ' . $this->getDisplayName()); + $this->writeLog('-> description: ' . $this->getDisplayName()); + $this->writeLog('-> path: ' . $this->getBinPath()); + $this->writeLog('-> params: ' . $this->getParams()); + $this->writeLog('-> start_type: ' . ($this->getStartType() != null ? $this->getStartType() : self::SERVICE_DEMAND_START)); + $this->writeLog('-> service: ' . ($this->getErrorControl() != null ? $this->getErrorControl() : self::SERVER_ERROR_NORMAL)); + + if ($create != self::WIN32_NO_ERROR) { return false; - } - elseif ( !$this->isInstalled() ) { + } elseif (!$this->isInstalled()) { $this->latestError = self::WIN32_NO_ERROR; return false; @@ -247,28 +256,26 @@ public function create() * * @return bool True if the service was deleted successfully, false otherwise. */ - public function delete() + public function delete(): bool { - if ( !$this->isInstalled() ) { + if (!$this->isInstalled()) { return true; } $this->stop(); - if ( $this->getName() == BinFilezilla::SERVICE_NAME ) { + if ($this->getName() == BinFilezilla::SERVICE_NAME) { return Batch::uninstallFilezillaService(); - } - elseif ( $this->getName() == BinPostgresql::SERVICE_NAME ) { + } elseif ($this->getName() == BinPostgresql::SERVICE_NAME) { return Batch::uninstallPostgresqlService(); } - $delete = dechex( $this->callWin32Service( 'win32_delete_service', $this->getName(), true ) ); - $this->writeLog( 'Delete service ' . $this->getName() . ': ' . $delete . ' (status: ' . $this->status() . ')' ); + $delete = dechex($this->callWin32Service('win32_delete_service', $this->getName(), true)); + $this->writeLog('Delete service ' . $this->getName() . ': ' . $delete . ' (status: ' . $this->status() . ')'); - if ( $delete != self::WIN32_NO_ERROR && $delete != self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST ) { + if ($delete != self::WIN32_NO_ERROR && $delete != self::WIN32_ERROR_SERVICE_DOES_NOT_EXIST) { return false; - } - elseif ( $this->isInstalled() ) { + } elseif ($this->isInstalled()) { $this->latestError = self::WIN32_NO_ERROR; return false; @@ -282,10 +289,10 @@ public function delete() * * @return bool True if the service was reset successfully, false otherwise. */ - public function reset() + public function reset(): bool { - if ( $this->delete() ) { - usleep( self::SLEEP_TIME ); + if ($this->delete()) { + usleep(self::SLEEP_TIME); return $this->create(); } @@ -298,78 +305,68 @@ public function reset() * * @return bool True if the service was started successfully, false otherwise. */ - public function start() + public function start(): bool { global $bearsamppBins; Util::logInfo('Attempting to start service: ' . $this->getName()); - if ( $this->getName() == BinFilezilla::SERVICE_NAME ) { + if ($this->getName() == BinFilezilla::SERVICE_NAME) { $bearsamppBins->getFilezilla()->rebuildConf(); - } - elseif ( $this->getName() == BinMysql::SERVICE_NAME ) { + } elseif ($this->getName() == BinMysql::SERVICE_NAME) { $bearsamppBins->getMysql()->initData(); - } - elseif ( $this->getName() == BinMailhog::SERVICE_NAME ) { + } elseif ($this->getName() == BinMailhog::SERVICE_NAME) { $bearsamppBins->getMailhog()->rebuildConf(); - } - elseif ( $this->getName() == BinMailpit::SERVICE_NAME ) { + } elseif ($this->getName() == BinMailpit::SERVICE_NAME) { $bearsamppBins->getMailpit()->rebuildConf(); - } - elseif ( $this->getName() == BinMemcached::SERVICE_NAME ) { + } elseif ($this->getName() == BinMemcached::SERVICE_NAME) { $bearsamppBins->getMemcached()->rebuildConf(); - } - elseif ( $this->getName() == BinPostgresql::SERVICE_NAME ) { + } elseif ($this->getName() == BinPostgresql::SERVICE_NAME) { $bearsamppBins->getPostgresql()->rebuildConf(); $bearsamppBins->getPostgresql()->initData(); - } - elseif ( $this->getName() == BinXlight::SERVICE_NAME ) { + } elseif ($this->getName() == BinXlight::SERVICE_NAME) { $bearsamppBins->getXlight()->rebuildConf(); } + $start = dechex($this->callWin32Service('win32_start_service', $this->getName(), true)); + Util::logDebug('Start service ' . $this->getName() . ': ' . $start . ' (status: ' . $this->status() . ')'); - $start = dechex( $this->callWin32Service( 'win32_start_service', $this->getName(), true ) ); - Util::logDebug( 'Start service ' . $this->getName() . ': ' . $start . ' (status: ' . $this->status() . ')' ); - - if ( $start != self::WIN32_NO_ERROR && $start != self::WIN32_ERROR_SERVICE_ALREADY_RUNNING ) { + if ($start != self::WIN32_NO_ERROR && $start != self::WIN32_ERROR_SERVICE_ALREADY_RUNNING) { // Write error to log Util::logError('Failed to start service: ' . $this->getName() . ' with error code: ' . $start); - if ( $this->getName() == BinApache::SERVICE_NAME ) { - $cmdOutput = $bearsamppBins->getApache()->getCmdLineOutput( BinApache::CMD_SYNTAX_CHECK ); - if ( !$cmdOutput['syntaxOk'] ) { + if ($this->getName() == BinApache::SERVICE_NAME) { + $cmdOutput = $bearsamppBins->getApache()->getCmdLineOutput(BinApache::CMD_SYNTAX_CHECK); + if (!$cmdOutput['syntaxOk']) { file_put_contents( $bearsamppBins->getApache()->getErrorLog(), - '[' . date( 'Y-m-d H:i:s', time() ) . '] [error] ' . $cmdOutput['content'] . PHP_EOL, + '[' . date('Y-m-d H:i:s') . '] [error] ' . $cmdOutput['content'] . PHP_EOL, FILE_APPEND ); } - } - elseif ( $this->getName() == BinMysql::SERVICE_NAME ) { - $cmdOutput = $bearsamppBins->getMysql()->getCmdLineOutput( BinMysql::CMD_SYNTAX_CHECK ); - if ( !$cmdOutput['syntaxOk'] ) { + } elseif ($this->getName() == BinMysql::SERVICE_NAME) { + $cmdOutput = $bearsamppBins->getMysql()->getCmdLineOutput(BinMysql::CMD_SYNTAX_CHECK); + if (!$cmdOutput['syntaxOk']) { file_put_contents( $bearsamppBins->getMysql()->getErrorLog(), - '[' . date( 'Y-m-d H:i:s', time() ) . '] [error] ' . $cmdOutput['content'] . PHP_EOL, + '[' . date('Y-m-d H:i:s') . '] [error] ' . $cmdOutput['content'] . PHP_EOL, FILE_APPEND ); } - } - elseif ( $this->getName() == BinMariadb::SERVICE_NAME ) { - $cmdOutput = $bearsamppBins->getMariadb()->getCmdLineOutput( BinMariadb::CMD_SYNTAX_CHECK ); - if ( !$cmdOutput['syntaxOk'] ) { + } elseif ($this->getName() == BinMariadb::SERVICE_NAME) { + $cmdOutput = $bearsamppBins->getMariadb()->getCmdLineOutput(BinMariadb::CMD_SYNTAX_CHECK); + if (!$cmdOutput['syntaxOk']) { file_put_contents( $bearsamppBins->getMariadb()->getErrorLog(), - '[' . date( 'Y-m-d H:i:s', time() ) . '] [error] ' . $cmdOutput['content'] . PHP_EOL, + '[' . date('Y-m-d H:i:s') . '] [error] ' . $cmdOutput['content'] . PHP_EOL, FILE_APPEND ); } } return false; - } - elseif ( !$this->isRunning() ) { + } elseif (!$this->isRunning()) { $this->latestError = self::WIN32_NO_ERROR; Util::logError('Service ' . $this->getName() . ' is not running after start attempt.'); $this->latestError = null; @@ -385,15 +382,14 @@ public function start() * * @return bool True if the service was stopped successfully, false otherwise. */ - public function stop() + public function stop(): bool { - $stop = dechex( $this->callWin32Service( 'win32_stop_service', $this->getName(), true ) ); - $this->writeLog( 'Stop service ' . $this->getName() . ': ' . $stop . ' (status: ' . $this->status() . ')' ); + $stop = dechex($this->callWin32Service('win32_stop_service', $this->getName(), true)); + $this->writeLog('Stop service ' . $this->getName() . ': ' . $stop . ' (status: ' . $this->status() . ')'); - if ( $stop != self::WIN32_NO_ERROR ) { + if ($stop != self::WIN32_NO_ERROR) { return false; - } - elseif ( !$this->isStopped() ) { + } elseif (!$this->isStopped()) { $this->latestError = self::WIN32_NO_ERROR; return false; @@ -407,9 +403,9 @@ public function stop() * * @return bool True if the service was restarted successfully, false otherwise. */ - public function restart() + public function restart(): bool { - if ( $this->stop() ) { + if ($this->stop()) { return $this->start(); } @@ -421,13 +417,13 @@ public function restart() * * @return array The service information. */ - public function infos() + public function infos(): array { - if ( $this->getNssm() instanceof Nssm ) { + if ($this->getNssm() instanceof Nssm) { return $this->getNssm()->infos(); } - return Vbs::getServiceInfos( $this->getName() ); + return Vbs::getServiceInfos($this->getName()); } /** @@ -435,10 +431,10 @@ public function infos() * * @return bool True if the service is installed, false otherwise. */ - public function isInstalled() + public function isInstalled(): bool { $status = $this->status(); - $this->writeLog( 'isInstalled ' . $this->getName() . ': ' . ($status != self::WIN32_SERVICE_NA ? 'YES' : 'NO') . ' (status: ' . $status . ')' ); + $this->writeLog('isInstalled ' . $this->getName() . ': ' . ($status != self::WIN32_SERVICE_NA ? 'YES' : 'NO') . ' (status: ' . $status . ')'); return $status != self::WIN32_SERVICE_NA; } @@ -448,10 +444,10 @@ public function isInstalled() * * @return bool True if the service is running, false otherwise. */ - public function isRunning() + public function isRunning(): bool { $status = $this->status(); - $this->writeLog( 'isRunning ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_RUNNING ? 'YES' : 'NO') . ' (status: ' . $status . ')' ); + $this->writeLog('isRunning ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_RUNNING ? 'YES' : 'NO') . ' (status: ' . $status . ')'); return $status == self::WIN32_SERVICE_RUNNING; } @@ -461,10 +457,10 @@ public function isRunning() * * @return bool True if the service is stopped, false otherwise. */ - public function isStopped() + public function isStopped(): bool { $status = $this->status(); - $this->writeLog( 'isStopped ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_STOPPED ? 'YES' : 'NO') . ' (status: ' . $status . ')' ); + $this->writeLog('isStopped ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_STOPPED ? 'YES' : 'NO') . ' (status: ' . $status . ')'); return $status == self::WIN32_SERVICE_STOPPED; } @@ -474,10 +470,10 @@ public function isStopped() * * @return bool True if the service is paused, false otherwise. */ - public function isPaused() + public function isPaused(): bool { $status = $this->status(); - $this->writeLog( 'isPaused ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_PAUSED ? 'YES' : 'NO') . ' (status: ' . $status . ')' ); + $this->writeLog('isPaused ' . $this->getName() . ': ' . ($status == self::WIN32_SERVICE_PAUSED ? 'YES' : 'NO') . ' (status: ' . $status . ')'); return $status == self::WIN32_SERVICE_PAUSED; } @@ -485,11 +481,11 @@ public function isPaused() /** * Checks if the service is in a pending state. * - * @param string $status The status to check. + * @param string $status The status to check. * * @return bool True if the service is in a pending state, false otherwise. */ - public function isPending($status) + public function isPending(string $status): bool { return $status == self::WIN32_SERVICE_START_PENDING || $status == self::WIN32_SERVICE_STOP_PENDING || $status == self::WIN32_SERVICE_CONTINUE_PENDING || $status == self::WIN32_SERVICE_PAUSE_PENDING; @@ -498,67 +494,39 @@ public function isPending($status) /** * Returns a description of the Win32 service status. * - * @param string $status The status code. + * @param string $status The status code. * * @return string|null The status description. */ - private function getWin32ServiceStatusDesc($status) + private function getWin32ServiceStatusDesc(string $status): ?string { - switch ( $status ) { - case self::WIN32_SERVICE_CONTINUE_PENDING: - return 'The service continue is pending.'; - break; - - case self::WIN32_SERVICE_PAUSE_PENDING: - return 'The service pause is pending.'; - break; - - case self::WIN32_SERVICE_PAUSED: - return 'The service is paused.'; - break; - - case self::WIN32_SERVICE_RUNNING: - return 'The service is running.'; - break; - - case self::WIN32_SERVICE_START_PENDING: - return 'The service is starting.'; - break; - - case self::WIN32_SERVICE_STOP_PENDING: - return 'The service is stopping.'; - break; - - case self::WIN32_SERVICE_STOPPED: - return 'The service is not running.'; - break; - - case self::WIN32_SERVICE_NA: - return 'Cannot retrieve service status.'; - break; - - default: - return null; - break; - } + return match ($status) { + self::WIN32_SERVICE_CONTINUE_PENDING => 'The service continue is pending.', + self::WIN32_SERVICE_PAUSE_PENDING => 'The service pause is pending.', + self::WIN32_SERVICE_PAUSED => 'The service is paused.', + self::WIN32_SERVICE_RUNNING => 'The service is running.', + self::WIN32_SERVICE_START_PENDING => 'The service is starting.', + self::WIN32_SERVICE_STOP_PENDING => 'The service is stopping.', + self::WIN32_SERVICE_STOPPED => 'The service is not running.', + self::WIN32_SERVICE_NA => 'Cannot retrieve service status.', + default => null, + }; } /** * Returns a description of the Win32 error code. * - * @param string $code The error code. + * @param string $code The error code. * * @return string|null The description of the error code, or null if the code is not recognized. */ - private function getWin32ErrorCodeDesc($code) + private function getWin32ErrorCodeDesc(string $code): ?string { - switch ( $code ) { - case self::WIN32_ERROR_ACCESS_DENIED: - return 'The handle to the SCM database does not have the appropriate access rights.'; + return match ($code) { + self::WIN32_ERROR_ACCESS_DENIED => 'The handle to the SCM database does not have the appropriate access rights.', // ... other cases ... - default: - return null; - } + default => null, + }; } /** @@ -566,7 +534,7 @@ private function getWin32ErrorCodeDesc($code) * * @return string The name of the service. */ - public function getName() + public function getName(): string { return $this->name; } @@ -574,9 +542,9 @@ public function getName() /** * Sets the name of the service. * - * @param string $name The name to set. + * @param string $name The name to set. */ - public function setName($name) + public function setName(string $name): void { $this->name = $name; } @@ -586,7 +554,7 @@ public function setName($name) * * @return string The display name of the service. */ - public function getDisplayName() + public function getDisplayName(): string { return $this->displayName; } @@ -594,9 +562,9 @@ public function getDisplayName() /** * Sets the display name of the service. * - * @param string $displayName The display name to set. + * @param string $displayName The display name to set. */ - public function setDisplayName($displayName) + public function setDisplayName(string $displayName): void { $this->displayName = $displayName; } @@ -606,7 +574,7 @@ public function setDisplayName($displayName) * * @return string The binary path of the service. */ - public function getBinPath() + public function getBinPath(): string { return $this->binPath; } @@ -614,11 +582,11 @@ public function getBinPath() /** * Sets the binary path of the service. * - * @param string $binPath The binary path to set. + * @param string $binPath The binary path to set. */ - public function setBinPath($binPath) + public function setBinPath(string $binPath): void { - $this->binPath = str_replace( '"', '', Util::formatWindowsPath( $binPath ) ); + $this->binPath = str_replace('"', '', Util::formatWindowsPath($binPath)); } /** @@ -626,7 +594,7 @@ public function setBinPath($binPath) * * @return string The parameters for the service. */ - public function getParams() + public function getParams(): string { return $this->params; } @@ -634,9 +602,9 @@ public function getParams() /** * Sets the parameters for the service. * - * @param string $params The parameters to set. + * @param string $params The parameters to set. */ - public function setParams($params) + public function setParams(string $params): void { $this->params = $params; } @@ -646,7 +614,7 @@ public function setParams($params) * * @return string The start type of the service. */ - public function getStartType() + public function getStartType(): string { return $this->startType; } @@ -654,9 +622,9 @@ public function getStartType() /** * Sets the start type of the service. * - * @param string $startType The start type to set. + * @param string $startType The start type to set. */ - public function setStartType($startType) + public function setStartType(string $startType): void { $this->startType = $startType; } @@ -666,7 +634,7 @@ public function setStartType($startType) * * @return string The error control setting of the service. */ - public function getErrorControl() + public function getErrorControl(): string { return $this->errorControl; } @@ -674,9 +642,9 @@ public function getErrorControl() /** * Sets the error control setting of the service. * - * @param string $errorControl The error control setting to set. + * @param string $errorControl The error control setting to set. */ - public function setErrorControl($errorControl) + public function setErrorControl(string $errorControl): void { $this->errorControl = $errorControl; } @@ -684,9 +652,9 @@ public function setErrorControl($errorControl) /** * Gets the NSSM instance associated with the service. * - * @return Nssm The NSSM instance. + * @return Nssm|null The NSSM instance. */ - public function getNssm() + public function getNssm(): ?Nssm { return $this->nssm; } @@ -694,17 +662,15 @@ public function getNssm() /** * Sets the NSSM instance associated with the service. * - * @param Nssm $nssm The NSSM instance to set. + * @param Nssm $nssm The NSSM instance to set. */ - public function setNssm($nssm) + public function setNssm(Nssm $nssm): void { - if ( $nssm instanceof Nssm ) { - $this->setDisplayName( $nssm->getDisplayName() ); - $this->setBinPath( $nssm->getBinPath() ); - $this->setParams( $nssm->getParams() ); - $this->setStartType( $nssm->getStart() ); - $this->nssm = $nssm; - } + $this->setDisplayName($nssm->getDisplayName()); + $this->setBinPath($nssm->getBinPath()); + $this->setParams($nssm->getParams()); + $this->setStartType($nssm->getStart()); + $this->nssm = $nssm; } /** @@ -712,7 +678,7 @@ public function setNssm($nssm) * * @return string The latest status of the service. */ - public function getLatestStatus() + public function getLatestStatus(): string { return $this->latestStatus; } @@ -722,7 +688,7 @@ public function getLatestStatus() * * @return string The latest error encountered by the service. */ - public function getLatestError() + public function getLatestError(): string { return $this->latestError; } @@ -732,16 +698,15 @@ public function getLatestError() * * @return string|null The detailed error message, or null if no error. */ - public function getError() + public function getError(): ?string { global $bearsamppLang; - if ( $this->latestError != self::WIN32_NO_ERROR ) { - return $bearsamppLang->getValue( Lang::ERROR ) . ' ' . - $this->latestError . ' (' . hexdec( $this->latestError ) . ' : ' . $this->getWin32ErrorCodeDesc( $this->latestError ) . ')'; - } - elseif ( $this->latestStatus != self::WIN32_SERVICE_NA ) { - return $bearsamppLang->getValue( Lang::STATUS ) . ' ' . - $this->latestStatus . ' (' . hexdec( $this->latestStatus ) . ' : ' . $this->getWin32ServiceStatusDesc( $this->latestStatus ) . ')'; + if ($this->latestError != self::WIN32_NO_ERROR) { + return $bearsamppLang->getValue(Lang::ERROR) . ' ' . + $this->latestError . ' (' . hexdec($this->latestError) . ' : ' . $this->getWin32ErrorCodeDesc($this->latestError) . ')'; + } elseif ($this->latestStatus != self::WIN32_SERVICE_NA) { + return $bearsamppLang->getValue(Lang::STATUS) . ' ' . + $this->latestStatus . ' (' . hexdec($this->latestStatus) . ' : ' . $this->getWin32ServiceStatusDesc($this->latestStatus) . ')'; } return null; diff --git a/core/classes/class.winbinder.php b/core/classes/class.winbinder.php index 0d48818b5..ce072134d 100644 --- a/core/classes/class.winbinder.php +++ b/core/classes/class.winbinder.php @@ -1,71 +1,60 @@ getWinbinderLogFilePath()); @@ -91,10 +80,10 @@ private static function writeLog($log) /** * Resets the control counter and callback array. */ - public function reset() + public function reset(): void { $this->countCtrls = 1000; - $this->callback = array(); + $this->callback = []; } /** @@ -105,15 +94,19 @@ public function reset() * @param bool $removeErrorHandler Whether to remove the error handler during the call. * * @return mixed The result of the function call. + * + * @throws \Throwable If an exception occurs and error handling is not suppressed. */ - private function callWinBinder($function, $params = array(), $removeErrorHandler = false) + private function callWinBinder(string $function, array $params = [], bool $removeErrorHandler = false): mixed { $result = false; if (function_exists($function)) { - if ($removeErrorHandler) { - $result = @call_user_func_array($function, $params); - } else { + try { $result = call_user_func_array($function, $params); + } catch (\Throwable $e) { + if (!$removeErrorHandler) { + throw $e; + } } } @@ -123,24 +116,33 @@ private function callWinBinder($function, $params = array(), $removeErrorHandler /** * Creates a new window. * - * @param mixed $parent The parent window or null for a top-level window. - * @param string $wclass The window class. - * @param string $caption The window caption. - * @param int $xPos The x-coordinate of the window. - * @param int $yPos The y-coordinate of the window. - * @param int $width The width of the window. - * @param int $height The height of the window. - * @param mixed $style The window style. - * @param mixed $params Additional parameters for the window. + * @param mixed $parent The parent window or null for a top-level window. + * @param string $wclass The window class. + * @param string $caption The window caption. + * @param int $xPos The x-coordinate of the window. + * @param int $yPos The y-coordinate of the window. + * @param int $width The width of the window. + * @param int $height The height of the window. + * @param mixed|null $style The window style. + * @param mixed|null $params Additional parameters for the window. * * @return mixed The created window object. */ - public function createWindow($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style = null, $params = null) - { + public function createWindow( + mixed $parent, + string $wclass, + string $caption, + int $xPos, + int $yPos, + int $width, + int $height, + mixed $style = null, + mixed $params = null + ): mixed { global $bearsamppCore; $caption = empty($caption) ? $this->defaultTitle : $this->defaultTitle . ' - ' . $caption; - $window = $this->callWinBinder('wb_create_window', array($parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style, $params)); + $window = $this->callWinBinder('wb_create_window', [$parent, $wclass, $caption, $xPos, $yPos, $width, $height, $style, $params]); // Set tiny window icon $this->setImage($window, $bearsamppCore->getIconsPath() . '/app.ico'); @@ -151,25 +153,34 @@ public function createWindow($parent, $wclass, $caption, $xPos, $yPos, $width, $ /** * Creates a new control. * - * @param mixed $parent The parent window or control. - * @param string $ctlClass The control class. - * @param string $caption The control caption. - * @param int $xPos The x-coordinate of the control. - * @param int $yPos The y-coordinate of the control. - * @param int $width The width of the control. - * @param int $height The height of the control. - * @param mixed $style The control style. - * @param mixed $params Additional parameters for the control. + * @param mixed $parent The parent window or control. + * @param string $ctlClass The control class. + * @param string $caption The control caption. + * @param int $xPos The x-coordinate of the control. + * @param int $yPos The y-coordinate of the control. + * @param int $width The width of the control. + * @param int $height The height of the control. + * @param mixed|null $style The control style. + * @param mixed|null $params Additional parameters for the control. * * @return array An array containing the control ID and object. */ - public function createControl($parent, $ctlClass, $caption, $xPos, $yPos, $width, $height, $style = null, $params = null) - { + public function createControl( + mixed $parent, + string $ctlClass, + string $caption, + int $xPos, + int $yPos, + int $width, + int $height, + mixed $style = null, + mixed $params = null + ): array { $this->countCtrls++; - return array( + return [ self::CTRL_ID => $this->countCtrls, - self::CTRL_OBJ => $this->callWinBinder('wb_create_control', array( + self::CTRL_OBJ => $this->callWinBinder('wb_create_control', [ $parent, $ctlClass, $caption, @@ -180,39 +191,49 @@ public function createControl($parent, $ctlClass, $caption, $xPos, $yPos, $width $this->countCtrls, $style, $params - )), - ); + ]), + ]; } /** * Creates a new application window. * - * @param string $caption The window caption. - * @param int $width The width of the window. - * @param int $height The height of the window. - * @param mixed $style The window style. - * @param mixed $params Additional parameters for the window. + * @param string $caption The window caption. + * @param int $width The width of the window. + * @param int $height The height of the window. + * @param mixed|null $style The window style. + * @param mixed|null $params Additional parameters for the window. * * @return mixed The created window object. */ - public function createAppWindow($caption, $width, $height, $style = null, $params = null) - { + public function createAppWindow( + string $caption, + int $width, + int $height, + mixed $style = null, + mixed $params = null + ): mixed { return $this->createWindow(null, AppWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params); } /** * Creates a new naked window. * - * @param string $caption The window caption. - * @param int $width The width of the window. - * @param int $height The height of the window. - * @param mixed $style The window style. - * @param mixed $params Additional parameters for the window. + * @param string $caption The window caption. + * @param int $width The width of the window. + * @param int $height The height of the window. + * @param mixed|null $style The window style. + * @param mixed|null $params Additional parameters for the window. * * @return mixed The created window object. */ - public function createNakedWindow($caption, $width, $height, $style = null, $params = null) - { + public function createNakedWindow( + string $caption, + int $width, + int $height, + mixed $style = null, + mixed $params = null + ): mixed { $window = $this->createWindow(null, NakedWindow, $caption, WBC_CENTER, WBC_CENTER, $width, $height, $style, $params); $this->setArea($window, $width, $height); @@ -224,9 +245,9 @@ public function createNakedWindow($caption, $width, $height, $style = null, $par * * @param mixed $window The window object to destroy. */ - public function destroyWindow($window) + public function destroyWindow(mixed $window): void { - $this->callWinBinder('wb_destroy_window', array($window), true); + $this->callWinBinder('wb_destroy_window', [$window], true); exit(); } @@ -235,7 +256,7 @@ public function destroyWindow($window) * * @return mixed The result of the main loop. */ - public function mainLoop() + public function mainLoop(): mixed { return $this->callWinBinder('wb_main_loop'); } @@ -247,9 +268,9 @@ public function mainLoop() * * @return mixed The result of the refresh operation. */ - public function refresh($wbobject) + public function refresh(mixed $wbobject): mixed { - return $this->callWinBinder('wb_refresh', array($wbobject, true)); + return $this->callWinBinder('wb_refresh', [$wbobject, true]); } /** @@ -259,9 +280,9 @@ public function refresh($wbobject) * * @return mixed The retrieved system information. */ - public function getSystemInfo($info) + public function getSystemInfo(string $info): mixed { - return $this->callWinBinder('wb_get_system_info', array($info)); + return $this->callWinBinder('wb_get_system_info', [$info]); } /** @@ -276,33 +297,46 @@ public function getSystemInfo($info) * * @return mixed The result of the draw operation. */ - public function drawImage($wbobject, $path, $xPos = 0, $yPos = 0, $width = 0, $height = 0) - { - $image = $this->callWinBinder('wb_load_image', array($path)); - - return $this->callWinBinder('wb_draw_image', array($wbobject, $image, $xPos, $yPos, $width, $height)); + public function drawImage( + mixed $wbobject, + string $path, + int $xPos = 0, + int $yPos = 0, + int $width = 0, + int $height = 0 + ): mixed { + $image = $this->callWinBinder('wb_load_image', [$path]); + + return $this->callWinBinder('wb_draw_image', [$wbobject, $image, $xPos, $yPos, $width, $height]); } /** * Draws text on a WinBinder object. * - * @param mixed $parent The parent WinBinder object. - * @param string $caption The text to draw. - * @param int $xPos The x-coordinate of the text. - * @param int $yPos The y-coordinate of the text. - * @param int|null $width The width of the text area. - * @param int|null $height The height of the text area. - * @param mixed $font The font to use for the text. + * @param mixed $parent The parent WinBinder object. + * @param string $caption The text to draw. + * @param int $xPos The x-coordinate of the text. + * @param int $yPos The y-coordinate of the text. + * @param int|null $width The width of the text area. + * @param int|null $height The height of the text area. + * @param mixed|null $font The font to use for the text. * * @return mixed The result of the draw operation. */ - public function drawText($parent, $caption, $xPos, $yPos, $width = null, $height = null, $font = null) - { + public function drawText( + mixed $parent, + string $caption, + int $xPos, + int $yPos, + ?int $width = null, + ?int $height = null, + mixed $font = null + ): mixed { $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption); - $width = $width == null ? 120 : $width; - $height = $height == null ? 25 : $height; + $width = $width ?? 120; + $height = $height ?? 25; - return $this->callWinBinder('wb_draw_text', array($parent, $caption, $xPos, $yPos, $width, $height, $font)); + return $this->callWinBinder('wb_draw_text', [$parent, $caption, $xPos, $yPos, $width, $height, $font]); } /** @@ -318,9 +352,16 @@ public function drawText($parent, $caption, $xPos, $yPos, $width = null, $height * * @return mixed The result of the draw operation. */ - public function drawRect($parent, $xPos, $yPos, $width, $height, $color = 15790320, $filled = true) - { - return $this->callWinBinder('wb_draw_rect', array($parent, $xPos, $yPos, $width, $height, $color, $filled)); + public function drawRect( + mixed $parent, + int $xPos, + int $yPos, + int $width, + int $height, + int $color = 15790320, + bool $filled = true + ): mixed { + return $this->callWinBinder('wb_draw_rect', [$parent, $xPos, $yPos, $width, $height, $color, $filled]); } /** @@ -336,36 +377,47 @@ public function drawRect($parent, $xPos, $yPos, $width, $height, $color = 157903 * * @return mixed The result of the draw operation. */ - public function drawLine($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height = 1) - { - return $this->callWinBinder('wb_draw_line', array($wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height)); + public function drawLine( + mixed $wbobject, + int $xStartPos, + int $yStartPos, + int $xEndPos, + int $yEndPos, + int $color, + int $height = 1 + ): mixed { + return $this->callWinBinder('wb_draw_line', [$wbobject, $xStartPos, $yStartPos, $xEndPos, $yEndPos, $color, $height]); } /** * Creates a font for use in WinBinder controls. * - * @param string $fontName The name of the font. - * @param int|null $size The size of the font. - * @param int|null $color The color of the font. - * @param mixed $style The style of the font. + * @param string $fontName The name of the font. + * @param int|null $size The size of the font. + * @param int|null $color The color of the font. + * @param mixed|null $style The style of the font. * * @return mixed The created font object. */ - public function createFont($fontName, $size = null, $color = null, $style = null) - { - return $this->callWinBinder('wb_create_font', array($fontName, $size, $color, $style)); + public function createFont( + string $fontName, + ?int $size = null, + ?int $color = null, + mixed $style = null + ): mixed { + return $this->callWinBinder('wb_create_font', [$fontName, $size, $color, $style]); } /** * Waits for an event on a WinBinder object. * - * @param mixed $wbobject The WinBinder object to wait on. + * @param mixed|null $wbobject The WinBinder object to wait on. * * @return mixed The result of the wait operation. */ - public function wait($wbobject = null) + public function wait(mixed $wbobject = null): mixed { - return $this->callWinBinder('wb_wait', array($wbobject), true); + return $this->callWinBinder('wb_wait', [$wbobject], true); } /** @@ -376,14 +428,14 @@ public function wait($wbobject = null) * * @return array An array containing the timer ID and object. */ - public function createTimer($wbobject, $wait = 1000) + public function createTimer(mixed $wbobject, int $wait = 1000): array { $this->countCtrls++; - return array( + return [ self::CTRL_ID => $this->countCtrls, - self::CTRL_OBJ => $this->callWinBinder('wb_create_timer', array($wbobject, $this->countCtrls, $wait)) - ); + self::CTRL_OBJ => $this->callWinBinder('wb_create_timer', [$wbobject, $this->countCtrls, $wait]) + ]; } /** @@ -394,9 +446,9 @@ public function createTimer($wbobject, $wait = 1000) * * @return mixed The result of the destroy operation. */ - public function destroyTimer($wbobject, $timerobject) + public function destroyTimer(mixed $wbobject, mixed $timerobject): mixed { - return $this->callWinBinder('wb_destroy_timer', array($wbobject, $timerobject)); + return $this->callWinBinder('wb_destroy_timer', [$wbobject, $timerobject]); } /** @@ -408,19 +460,19 @@ public function destroyTimer($wbobject, $timerobject) * * @return mixed The result of the command execution. */ - public function exec($cmd, $params = null, $silent = false) + public function exec(string $cmd, ?string $params = null, bool $silent = false): mixed { global $bearsamppCore; if ($silent) { - $silent = '"' . $bearsamppCore->getScript(Core::SCRIPT_EXEC_SILENT) . '" "' . $cmd . '"'; - $cmd = 'wscript.exe'; - $params = !empty($params) ? $silent . ' "' . $params . '"' : $silent; + $silentScript = '"' . $bearsamppCore->getScript(Core::SCRIPT_EXEC_SILENT) . '" "' . $cmd . '"'; + $cmd = 'wscript.exe'; + $params = !empty($params) ? $silentScript . ' "' . $params . '"' : $silentScript; } $this->writeLog('exec: ' . $cmd . ' ' . $params); - return $this->callWinBinder('wb_exec', array($cmd, $params)); + return $this->callWinBinder('wb_exec', [$cmd, $params]); } /** @@ -430,33 +482,42 @@ public function exec($cmd, $params = null, $silent = false) * * @return mixed The result of the find operation. */ - public function findFile($filename) + public function findFile(string $filename): mixed { - $result = $this->callWinBinder('wb_find_file', array($filename)); + $result = $this->callWinBinder('wb_find_file', [$filename]); $this->writeLog('findFile ' . $filename . ': ' . $result); - return $result != $filename ? $result : false; + return $result !== $filename ? $result : false; } /** * Sets an event handler for a WinBinder object. * - * @param mixed $wbobject The WinBinder object to set the handler for. - * @param mixed $classCallback The class callback for the handler. - * @param mixed $methodCallback The method callback for the handler. - * @param mixed $launchTimer The timer to launch for the handler. + * @param mixed $wbobject The WinBinder object to set the handler for. + * @param mixed $classCallback The class callback for the handler. + * @param mixed $methodCallback The method callback for the handler. + * @param mixed|null $launchTimer The timer to launch for the handler. * * @return mixed The result of the set handler operation. */ - public function setHandler($wbobject, $classCallback, $methodCallback, $launchTimer = null) - { - if ($launchTimer != null) { - $launchTimer = $this->createTimer($wbobject, $launchTimer); + public function setHandler( + mixed $wbobject, + mixed $classCallback, + mixed $methodCallback, + mixed $launchTimer = null + ): mixed { + if ($launchTimer !== null) { + $launchTimer = $this->createTimer($wbobject, (int)$launchTimer); } - $this->callback[$wbobject] = array($classCallback, $methodCallback, $launchTimer); + $this->callback[$wbobject] = [$classCallback, $methodCallback, $launchTimer]; - return $this->callWinBinder('wb_set_handler', array($wbobject, '__winbinderEventHandler')); + return $this->callWinBinder('wb_set_handler', [ + $wbobject, + function ($window, $id, $ctrl, $param1, $param2) { + $this->__winbinderEventHandler($window, $id, $ctrl, $param1, $param2); + } + ]); } /** @@ -467,7 +528,7 @@ public function setHandler($wbobject, $classCallback, $methodCallback, $launchTi * * @return mixed The result of the set image operation. */ - public function setImage($wbobject, $path) + public function setImage(mixed $wbobject, string $path): mixed { if ($wbobject === null) { error_log('Error: $wbobject is null.'); @@ -481,7 +542,7 @@ public function setImage($wbobject, $path) return false; } - return $this->callWinBinder('wb_set_image', array($wbobject, $path)); + return $this->callWinBinder('wb_set_image', [$wbobject, $path]); } /** @@ -492,9 +553,9 @@ public function setImage($wbobject, $path) * * @return mixed The result of the set maximum length operation. */ - public function setMaxLength($wbobject, $length) + public function setMaxLength(mixed $wbobject, int $length): mixed { - return $this->callWinBinder('wb_send_message', array($wbobject, 0x00c5, $length, 0)); + return $this->callWinBinder('wb_send_message', [$wbobject, 0x00c5, $length, 0]); } /** @@ -506,9 +567,9 @@ public function setMaxLength($wbobject, $length) * * @return mixed The result of the set area operation. */ - public function setArea($wbobject, $width, $height) + public function setArea(mixed $wbobject, int $width, int $height): mixed { - return $this->callWinBinder('wb_set_area', array($wbobject, WBC_TITLE, 0, 0, $width, $height)); + return $this->callWinBinder('wb_set_area', [$wbobject, WBC_TITLE, 0, 0, $width, $height]); } /** @@ -518,9 +579,9 @@ public function setArea($wbobject, $width, $height) * * @return mixed The retrieved text. */ - public function getText($wbobject) + public function getText(mixed $wbobject): mixed { - return $this->callWinBinder('wb_get_text', array($wbobject)); + return $this->callWinBinder('wb_get_text', [$wbobject]); } /** @@ -531,11 +592,11 @@ public function getText($wbobject) * * @return mixed The result of the set text operation. */ - public function setText($wbobject, $content) + public function setText(mixed $wbobject, string $content): mixed { $content = str_replace(self::NEW_LINE, PHP_EOL, $content); - return $this->callWinBinder('wb_set_text', array($wbobject, $content)); + return $this->callWinBinder('wb_set_text', [$wbobject, $content]); } /** @@ -545,9 +606,9 @@ public function setText($wbobject, $content) * * @return mixed The retrieved value. */ - public function getValue($wbobject) + public function getValue(mixed $wbobject): mixed { - return $this->callWinBinder('wb_get_value', array($wbobject)); + return $this->callWinBinder('wb_get_value', [$wbobject]); } /** @@ -558,9 +619,9 @@ public function getValue($wbobject) * * @return mixed The result of the set value operation. */ - public function setValue($wbobject, $content) + public function setValue(mixed $wbobject, mixed $content): mixed { - return $this->callWinBinder('wb_set_value', array($wbobject, $content)); + return $this->callWinBinder('wb_set_value', [$wbobject, $content]); } /** @@ -568,7 +629,7 @@ public function setValue($wbobject, $content) * * @return mixed The WinBinder object that has the focus. */ - public function getFocus() + public function getFocus(): mixed { return $this->callWinBinder('wb_get_focus'); } @@ -580,9 +641,9 @@ public function getFocus() * * @return mixed The result of the set focus operation. */ - public function setFocus($wbobject) + public function setFocus(mixed $wbobject): mixed { - return $this->callWinBinder('wb_set_focus', array($wbobject)); + return $this->callWinBinder('wb_set_focus', [$wbobject]); } /** @@ -593,9 +654,9 @@ public function setFocus($wbobject) * * @return mixed The result of the set cursor operation. */ - public function setCursor($wbobject, $type = self::CURSOR_ARROW) + public function setCursor(mixed $wbobject, string $type = self::CURSOR_ARROW): mixed { - return $this->callWinBinder('wb_set_cursor', array($wbobject, $type)); + return $this->callWinBinder('wb_set_cursor', [$wbobject, $type]); } /** @@ -605,9 +666,9 @@ public function setCursor($wbobject, $type = self::CURSOR_ARROW) * * @return mixed True if the object is enabled, false otherwise. */ - public function isEnabled($wbobject) + public function isEnabled(mixed $wbobject): mixed { - return $this->callWinBinder('wb_get_enabled', array($wbobject)); + return $this->callWinBinder('wb_get_enabled', [$wbobject]); } /** @@ -618,9 +679,9 @@ public function isEnabled($wbobject) * * @return mixed The result of the set enabled state operation. */ - public function setEnabled($wbobject, $enabled = true) + public function setEnabled(mixed $wbobject, bool $enabled = true): mixed { - return $this->callWinBinder('wb_set_enabled', array($wbobject, $enabled)); + return $this->callWinBinder('wb_set_enabled', [$wbobject, $enabled]); } /** @@ -630,7 +691,7 @@ public function setEnabled($wbobject, $enabled = true) * * @return mixed The result of the disable operation. */ - public function setDisabled($wbobject) + public function setDisabled(mixed $wbobject): mixed { return $this->setEnabled($wbobject, false); } @@ -643,9 +704,9 @@ public function setDisabled($wbobject) * * @return mixed The result of the set style operation. */ - public function setStyle($wbobject, $style) + public function setStyle(mixed $wbobject, mixed $style): mixed { - return $this->callWinBinder('wb_set_style', array($wbobject, $style)); + return $this->callWinBinder('wb_set_style', [$wbobject, $style]); } /** @@ -657,9 +718,9 @@ public function setStyle($wbobject, $style) * * @return mixed The result of the set range operation. */ - public function setRange($wbobject, $min, $max) + public function setRange(mixed $wbobject, int $min, int $max): mixed { - return $this->callWinBinder('wb_set_range', array($wbobject, $min, $max)); + return $this->callWinBinder('wb_set_range', [$wbobject, $min, $max]); } /** @@ -671,9 +732,9 @@ public function setRange($wbobject, $min, $max) * * @return mixed The selected path. */ - public function sysDlgPath($parent, $title, $path = null) + public function sysDlgPath(mixed $parent, string $title, ?string $path = null): mixed { - return $this->callWinBinder('wb_sys_dlg_path', array($parent, $title, $path)); + return $this->callWinBinder('wb_sys_dlg_path', [$parent, $title, $path]); } /** @@ -686,9 +747,9 @@ public function sysDlgPath($parent, $title, $path = null) * * @return mixed The selected file path. */ - public function sysDlgOpen($parent, $title, $filter = null, $path = null) + public function sysDlgOpen(mixed $parent, string $title, ?string $filter = null, ?string $path = null): mixed { - return $this->callWinBinder('wb_sys_dlg_open', array($parent, $title, $filter, $path)); + return $this->callWinBinder('wb_sys_dlg_open', [$parent, $title, $filter, $path]); } /** @@ -705,11 +766,11 @@ public function sysDlgOpen($parent, $title, $filter = null, $path = null) * * @return array An array containing the control ID and object. */ - public function createLabel($parent, $caption, $xPos, $yPos, $width = null, $height = null, $style = null, $params = null) + public function createLabel(mixed $parent, string $caption, int $xPos, int $yPos, ?int $width = null, ?int $height = null, mixed $style = null, mixed $params = null): array { $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption); - $width = $width == null ? 120 : $width; - $height = $height == null ? 25 : $height; + $width = $width ?? 120; + $height = $height ?? 25; return $this->createControl($parent, Label, $caption, $xPos, $yPos, $width, $height, $style, $params); } @@ -729,12 +790,21 @@ public function createLabel($parent, $caption, $xPos, $yPos, $width = null, $hei * * @return array An array containing the control ID and object. */ - public function createInputText($parent, $value, $xPos, $yPos, $width = null, $height = null, $maxLength = null, $style = null, $params = null) - { + public function createInputText( + mixed $parent, + string $value, + int $xPos, + int $yPos, + ?int $width = null, + ?int $height = null, + ?int $maxLength = null, + mixed $style = null, + mixed $params = null + ): array { $value = str_replace(self::NEW_LINE, PHP_EOL, $value); - $width = $width == null ? 120 : $width; - $height = $height == null ? 25 : $height; - $inputText = $this->createControl($parent, EditBox, (string)$value, $xPos, $yPos, $width, $height, $style, $params); + $width = $width ?? 120; + $height = $height ?? 25; + $inputText = $this->createControl($parent, EditBox, $value, $xPos, $yPos, $width, $height, $style, $params); if (is_numeric($maxLength) && $maxLength > 0) { $this->setMaxLength($inputText[self::CTRL_OBJ], $maxLength); } @@ -756,12 +826,12 @@ public function createInputText($parent, $value, $xPos, $yPos, $width = null, $h * * @return array An array containing the control ID and object. */ - public function createEditBox($parent, $value, $xPos, $yPos, $width = null, $height = null, $style = null, $params = null) + public function createEditBox(mixed $parent, string $value, int $xPos, int $yPos, ?int $width = null, ?int $height = null, mixed $style = null, mixed $params = null): array { $value = str_replace(self::NEW_LINE, PHP_EOL, $value); - $width = $width == null ? 540 : $width; - $height = $height == null ? 340 : $height; - $editBox = $this->createControl($parent, RTFEditBox, (string)$value, $xPos, $yPos, $width, $height, $style, $params); + $width = $width ?? 540; + $height = $height ?? 340; + $editBox = $this->createControl($parent, RTFEditBox, $value, $xPos, $yPos, $width, $height, $style, $params); return $editBox; } @@ -780,12 +850,12 @@ public function createEditBox($parent, $value, $xPos, $yPos, $width = null, $hei * * @return array An array containing the control ID and object. */ - public function createHyperLink($parent, $caption, $xPos, $yPos, $width = null, $height = null, $style = null, $params = null) + public function createHyperLink(mixed $parent, string $caption, int $xPos, int $yPos, ?int $width = null, ?int $height = null, mixed $style = null, mixed $params = null): array { $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption); - $width = $width == null ? 120 : $width; - $height = $height == null ? 15 : $height; - $hyperLink = $this->createControl($parent, HyperLink, (string)$caption, $xPos, $yPos, $width, $height, $style, $params); + $width = $width ?? 120; + $height = $height ?? 15; + $hyperLink = $this->createControl($parent, HyperLink, $caption, $xPos, $yPos, $width, $height, $style, $params); $this->setCursor($hyperLink[self::CTRL_OBJ], self::CURSOR_FINGER); return $hyperLink; @@ -805,13 +875,13 @@ public function createHyperLink($parent, $caption, $xPos, $yPos, $width = null, * * @return array An array containing the control ID and object. */ - public function createRadioButton($parent, $caption, $checked, $xPos, $yPos, $width = null, $height = null, $startGroup = false) + public function createRadioButton(mixed $parent, string $caption, bool $checked, int $xPos, int $yPos, ?int $width = null, ?int $height = null, bool $startGroup = false): array { $caption = str_replace(self::NEW_LINE, PHP_EOL, $caption); - $width = $width == null ? 120 : $width; - $height = $height == null ? 25 : $height; + $width = $width ?? 120; + $height = $height ?? 25; - return $this->createControl($parent, RadioButton, (string)$caption, $xPos, $yPos, $width, $height, $startGroup ? WBC_GROUP : null, $checked ? 1 : 0); + return $this->createControl($parent, RadioButton, $caption, $xPos, $yPos, $width, $height, $startGroup ? WBC_GROUP : null, $checked ? 1 : 0); } /** @@ -828,10 +898,10 @@ public function createRadioButton($parent, $caption, $checked, $xPos, $yPos, $wi * * @return array An array containing the control ID and object. */ - public function createButton($parent, $caption, $xPos, $yPos, $width = null, $height = null, $style = null, $params = null) + public function createButton(mixed $parent, string $caption, int $xPos, int $yPos, ?int $width = null, ?int $height = null, mixed $style = null, mixed $params = null): array { - $width = $width == null ? 80 : $width; - $height = $height == null ? 25 : $height; + $width = $width ?? 80; + $height = $height ?? 25; return $this->createControl($parent, PushButton, $caption, $xPos, $yPos, $width, $height, $style, $params); } @@ -850,12 +920,12 @@ public function createButton($parent, $caption, $xPos, $yPos, $width = null, $he * * @return array An array containing the control ID and object. */ - public function createProgressBar($parent, $max, $xPos, $yPos, $width = null, $height = null, $style = null, $params = null) + public function createProgressBar(mixed $parent, int $max, int $xPos, int $yPos, ?int $width = null, ?int $height = null, mixed $style = null, mixed $params = null): array { global $bearsamppLang; - $width = $width == null ? 200 : $width; - $height = $height == null ? 15 : $height; + $width = $width ?? 200; + $height = $height ?? 15; $progressBar = $this->createControl($parent, Gauge, $bearsamppLang->getValue(Lang::LOADING), $xPos, $yPos, $width, $height, $style, $params); $this->setRange($progressBar[self::CTRL_OBJ], 0, $max); @@ -869,7 +939,7 @@ public function createProgressBar($parent, $max, $xPos, $yPos, $width = null, $h * * @param array $progressBar The progress bar control. */ - public function incrProgressBar($progressBar) + public function incrProgressBar(array $progressBar): void { $this->setProgressBarValue($progressBar, self::INCR_PROGRESS_BAR); } @@ -879,7 +949,7 @@ public function incrProgressBar($progressBar) * * @param array $progressBar The progress bar control. */ - public function resetProgressBar($progressBar) + public function resetProgressBar(array $progressBar): void { $this->setProgressBarValue($progressBar, 0); } @@ -890,10 +960,10 @@ public function resetProgressBar($progressBar) * @param array $progressBar The progress bar control. * @param mixed $value The value to set. */ - public function setProgressBarValue($progressBar, $value) + public function setProgressBarValue(array $progressBar, mixed $value): void { - if ($progressBar != null && isset($progressBar[self::CTRL_OBJ]) && isset($this->gauge[$progressBar[self::CTRL_OBJ]])) { - if (strval($value) == self::INCR_PROGRESS_BAR) { + if ($progressBar !== null && isset($progressBar[self::CTRL_OBJ]) && isset($this->gauge[$progressBar[self::CTRL_OBJ]])) { + if (strval($value) === self::INCR_PROGRESS_BAR) { $value = $this->gauge[$progressBar[self::CTRL_OBJ]] + 1; } if (is_numeric($value)) { @@ -909,7 +979,7 @@ public function setProgressBarValue($progressBar, $value) * @param array $progressBar The progress bar control. * @param int $max The maximum value to set. */ - public function setProgressBarMax($progressBar, $max) + public function setProgressBarMax(array $progressBar, int $max): void { $this->setRange($progressBar[self::CTRL_OBJ], 0, $max); } @@ -923,36 +993,31 @@ public function setProgressBarMax($progressBar, $max) * * @return mixed The result of the message box operation. */ - public function messageBox($message, $type, $title = null) + public function messageBox(string $message, int $type, ?string $title = null): mixed { global $bearsamppCore; $message = str_replace(self::NEW_LINE, PHP_EOL, $message); - $messageBox = $this->callWinBinder('wb_message_box', array( + $messageBox = $this->callWinBinder('wb_message_box', [ null, - strlen($message) < 64 ? str_pad($message, 64) : $message, // Pad message to display entire title - $title == null ? $this->defaultTitle : $this->defaultTitle . ' - ' . $title, + strlen($message) < 64 ? str_pad($message, 64) : $message, + $title === null ? $this->defaultTitle : $this->defaultTitle . ' - ' . $title, $type - )); + ]); - // TODO why does this create an error sometimes. - // Set tiny window icon - // Ensure $messageBox is not null if ($messageBox === null) { error_log('Error: $messageBox is null.'); - return; + return null; } - // Ensure the icon path is correct and the file exists $iconPath = $bearsamppCore->getIconsPath() . '/app.ico'; if (!file_exists($iconPath)) { error_log('Error: Icon file does not exist at path: ' . $iconPath); - return; + return null; } - // Call the setImage method $this->setImage($messageBox, $iconPath); return $messageBox; @@ -966,7 +1031,7 @@ public function messageBox($message, $type, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxInfo($message, $title = null) + public function messageBoxInfo(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_INFO, $title); } @@ -979,7 +1044,7 @@ public function messageBoxInfo($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxOk($message, $title = null) + public function messageBoxOk(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_OK, $title); } @@ -992,7 +1057,7 @@ public function messageBoxOk($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxOkCancel($message, $title = null) + public function messageBoxOkCancel(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_OKCANCEL, $title); } @@ -1005,7 +1070,7 @@ public function messageBoxOkCancel($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxQuestion($message, $title = null) + public function messageBoxQuestion(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_QUESTION, $title); } @@ -1018,7 +1083,7 @@ public function messageBoxQuestion($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxError($message, $title = null) + public function messageBoxError(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_ERROR, $title); } @@ -1031,7 +1096,7 @@ public function messageBoxError($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxWarning($message, $title = null) + public function messageBoxWarning(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_WARNING, $title); } @@ -1044,7 +1109,7 @@ public function messageBoxWarning($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxYesNo($message, $title = null) + public function messageBoxYesNo(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_YESNO, $title); } @@ -1057,36 +1122,29 @@ public function messageBoxYesNo($message, $title = null) * * @return mixed The result of the message box operation. */ - public function messageBoxYesNoCancel($message, $title = null) + public function messageBoxYesNoCancel(string $message, ?string $title = null): mixed { return $this->messageBox($message, self::BOX_YESNOCANCEL, $title); } -} - -/** - * Event handler for WinBinder events. - * - * This function is called by WinBinder when an event occurs. It retrieves the callback - * associated with the window and executes it. If a timer is associated with the callback, - * the timer is destroyed before executing the callback. - * - * @param mixed $window The window object where the event occurred. - * @param int $id The ID of the event. - * @param mixed $ctrl The control that triggered the event. - * @param mixed $param1 The first parameter of the event. - * @param mixed $param2 The second parameter of the event. - */ -function __winbinderEventHandler($window, $id, $ctrl, $param1, $param2) -{ - global $bearsamppWinbinder; + /** + * Event handler for WinBinder events. + * + * @param mixed $window The window object where the event occurred. + * @param int $id The ID of the event. + * @param mixed $ctrl The control that triggered the event. + * @param mixed $param1 The first parameter of the event. + * @param mixed $param2 The second parameter of the event. + */ + private function __winbinderEventHandler(mixed $window, int $id, mixed $ctrl, mixed $param1, mixed $param2): void + { + if (isset($this->callback[$window][2])) { + $this->destroyTimer($window, $this->callback[$window][2][0]); + } - if ($bearsamppWinbinder->callback[$window][2] != null) { - $bearsamppWinbinder->destroyTimer($window, $bearsamppWinbinder->callback[$window][2][0]); + call_user_func_array( + [$this->callback[$window][0], $this->callback[$window][1]], + [$window, $id, $ctrl, $param1, $param2] + ); } - - call_user_func_array( - array($bearsamppWinbinder->callback[$window][0], $bearsamppWinbinder->callback[$window][1]), - array($window, $id, $ctrl, $param1, $param2) - ); }