diff --git a/image/README/1758393851516.png b/image/README/1758393851516.png deleted file mode 100644 index c6cd0cf4b..000000000 Binary files a/image/README/1758393851516.png and /dev/null differ diff --git a/image/README/1758393879941.png b/image/README/1758393879941.png deleted file mode 100644 index 86f0b1790..000000000 Binary files a/image/README/1758393879941.png and /dev/null differ diff --git a/managePHP/phpManager.py b/managePHP/phpManager.py index b5c8972c2..ad03e017f 100644 --- a/managePHP/phpManager.py +++ b/managePHP/phpManager.py @@ -12,50 +12,145 @@ class PHPManager: @staticmethod def findPHPVersions(): - # distro = ProcessUtilities.decideDistro() - # if distro == ProcessUtilities.centos: - # return ['PHP 5.3', 'PHP 5.4', 'PHP 5.5', 'PHP 5.6', 'PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - # elif distro == ProcessUtilities.cent8: - # return ['PHP 7.1','PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - # elif distro == ProcessUtilities.ubuntu20: - # return ['PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1'] - # else: - # return ['PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1', 'PHP 8.2', 'PHP 8.3', 'PHP 8.4', 'PHP 8.5'] - + """ + Comprehensive PHP version detection that checks multiple locations and methods + """ try: - - # Run the shell command and capture the output - result = ProcessUtilities.outputExecutioner('ls -la /usr/local/lsws') - - # Get the lines containing 'lsphp' in the output - lsphp_lines = [line for line in result.split('\n') if 'lsphp' in line] - - - if os.path.exists(ProcessUtilities.debugPath): - from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging - logging.writeToFile(f'Found PHP lines in findPHPVersions: {lsphp_lines}') - - - # Extract the version from the lines and format it as 'PHP x.y' - php_versions = ['PHP ' + line.split()[8][5] + '.' + line.split()[8][6:] for line in lsphp_lines] - finalPHPVersions = [] - for php in php_versions: - phpString = PHPManager.getPHPString(php) + + # Method 1: Check /usr/local/lsws directory (LiteSpeed PHP) + try: + result = ProcessUtilities.outputExecutioner('ls -la /usr/local/lsws') + lsphp_lines = [line for line in result.split('\n') if 'lsphp' in line] - if os.path.exists("/usr/local/lsws/lsphp" + str(phpString) + "/bin/lsphp"): - finalPHPVersions.append(php) + if os.path.exists(ProcessUtilities.debugPath): + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Found PHP lines in findPHPVersions: {lsphp_lines}') + + # Parse lsphp directories + for line in lsphp_lines: + try: + parts = line.split() + if len(parts) >= 9: + for part in parts: + if part.startswith('lsphp') and part != 'lsphp': + version_part = part[5:] # Remove 'lsphp' prefix + if len(version_part) >= 2: + major = version_part[0] + minor = version_part[1:] + formatted_version = f'PHP {major}.{minor}' + + # Validate the PHP installation + phpString = PHPManager.getPHPString(formatted_version) + php_path = f"/usr/local/lsws/lsphp{phpString}/bin/php" + lsphp_path = f"/usr/local/lsws/lsphp{phpString}/bin/lsphp" + + if os.path.exists(php_path) or os.path.exists(lsphp_path): + if formatted_version not in finalPHPVersions: + finalPHPVersions.append(formatted_version) + except (IndexError, ValueError): + continue + except Exception as e: + if os.path.exists(ProcessUtilities.debugPath): + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Error checking /usr/local/lsws: {str(e)}') + + # Method 2: Check system-wide PHP installations + try: + # Check for system PHP versions + system_php_versions = ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] + for version in system_php_versions: + formatted_version = f'PHP {version}' + if formatted_version not in finalPHPVersions: + # Check if this version exists in system + try: + phpString = PHPManager.getPHPString(formatted_version) + php_path = f"/usr/local/lsws/lsphp{phpString}/bin/php" + lsphp_path = f"/usr/local/lsws/lsphp{phpString}/bin/lsphp" + + if os.path.exists(php_path) or os.path.exists(lsphp_path): + finalPHPVersions.append(formatted_version) + except: + continue + except Exception as e: + if os.path.exists(ProcessUtilities.debugPath): + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Error checking system PHP: {str(e)}') + + # Method 3: Check package manager for available PHP versions + try: + # Try to detect available PHP packages + if ProcessUtilities.decideDistro() in [ProcessUtilities.centos, ProcessUtilities.cent8]: + # For CentOS/RHEL/AlmaLinux + command = "yum list available | grep lsphp | grep -E 'lsphp[0-9]+' | head -20" + else: + # For Ubuntu/Debian + command = "apt list --installed | grep lsphp | grep -E 'lsphp[0-9]+' | head -20" + + result = ProcessUtilities.outputExecutioner(command) + if result and result.strip(): + for line in result.split('\n'): + if 'lsphp' in line: + # Extract version from package name + import re + match = re.search(r'lsphp(\d+)(\d+)', line) + if match: + major = match.group(1) + minor = match.group(2) + formatted_version = f'PHP {major}.{minor}' + + if formatted_version not in finalPHPVersions: + # Validate installation + try: + phpString = PHPManager.getPHPString(formatted_version) + php_path = f"/usr/local/lsws/lsphp{phpString}/bin/php" + lsphp_path = f"/usr/local/lsws/lsphp{phpString}/bin/lsphp" + + if os.path.exists(php_path) or os.path.exists(lsphp_path): + finalPHPVersions.append(formatted_version) + except: + continue + except Exception as e: + if os.path.exists(ProcessUtilities.debugPath): + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Error checking package manager: {str(e)}') + + # Method 4: Fallback to checking common PHP versions + if not finalPHPVersions: + fallback_versions = ['PHP 7.4', 'PHP 8.0', 'PHP 8.1', 'PHP 8.2', 'PHP 8.3', 'PHP 8.4', 'PHP 8.5'] + for version in fallback_versions: + try: + phpString = PHPManager.getPHPString(version) + php_path = f"/usr/local/lsws/lsphp{phpString}/bin/php" + lsphp_path = f"/usr/local/lsws/lsphp{phpString}/bin/lsphp" + if os.path.exists(php_path) or os.path.exists(lsphp_path): + finalPHPVersions.append(version) + except: + continue + + # Sort versions (newest first) + def version_sort_key(version): + try: + # Extract version number for sorting + version_num = version.replace('PHP ', '').split('.') + major = int(version_num[0]) + minor = int(version_num[1]) if len(version_num) > 1 else 0 + return (major, minor) + except: + return (0, 0) + + finalPHPVersions.sort(key=version_sort_key, reverse=True) if os.path.exists(ProcessUtilities.debugPath): from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging - logging.writeToFile(f'Found PHP versions in findPHPVersions: {finalPHPVersions}') + logging.writeToFile(f'Final PHP versions found: {finalPHPVersions}') + + return finalPHPVersions if finalPHPVersions else ['PHP 7.4', 'PHP 8.0', 'PHP 8.1', 'PHP 8.2', 'PHP 8.3', 'PHP 8.4', 'PHP 8.5'] - # Now php_versions contains the formatted PHP versions - return finalPHPVersions except BaseException as msg: from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging logging.writeToFile(f'Error while finding php versions on system: {str(msg)}') - return ['PHP 7.0', 'PHP 7.1', 'PHP 7.2', 'PHP 7.3', 'PHP 7.4', 'PHP 8.0', 'PHP 8.1', 'PHP 8.2', 'PHP 8.3', 'PHP 8.4', 'PHP 8.5'] + return ['PHP 7.4', 'PHP 8.0', 'PHP 8.1', 'PHP 8.2', 'PHP 8.3', 'PHP 8.4', 'PHP 8.5'] @staticmethod def findApachePHPVersions(): @@ -137,6 +232,127 @@ class PHPManager: return php + @staticmethod + def validatePHPInstallation(phpVersion): + """ + Validate that a PHP installation is properly configured and accessible + Returns: (is_valid, error_message, php_path) + """ + try: + php = PHPManager.getPHPString(phpVersion) + php_path = f'/usr/local/lsws/lsphp{php}/bin/php' + lsphp_path = f'/usr/local/lsws/lsphp{php}/bin/lsphp' + + # Check if PHP binary exists + if os.path.exists(php_path): + return True, None, php_path + elif os.path.exists(lsphp_path): + return True, None, lsphp_path + else: + # Try alternative locations + alternative_paths = [ + f'/usr/local/lsws/lsphp{php}/bin/lsphp', + '/usr/bin/php', + '/usr/local/bin/php' + ] + + for alt_path in alternative_paths: + if os.path.exists(alt_path): + return True, None, alt_path + + return False, f'PHP {phpVersion} binary not found. Please install or check PHP installation.', None + + except Exception as e: + return False, f'Error validating PHP installation: {str(e)}', None + + @staticmethod + def fixPHPConfiguration(phpVersion): + """ + Attempt to fix common PHP configuration issues + """ + try: + php = PHPManager.getPHPString(phpVersion) + php_dir = f'/usr/local/lsws/lsphp{php}' + + # Check if PHP directory exists + if not os.path.exists(php_dir): + return False, f'PHP directory {php_dir} does not exist' + + # Check for missing php binary and create symlink if needed + php_binary = f'{php_dir}/bin/php' + lsphp_binary = f'{php_dir}/bin/lsphp' + + if not os.path.exists(php_binary) and os.path.exists(lsphp_binary): + # Create symlink from lsphp to php + import subprocess + subprocess.run(['ln', '-sf', 'lsphp', 'php'], cwd=f'{php_dir}/bin') + return True, 'PHP binary symlink created successfully' + + return True, 'PHP configuration appears to be correct' + + except Exception as e: + return False, f'Error fixing PHP configuration: {str(e)}' + + @staticmethod + def getLatestPHPVersion(): + """ + Get the latest available PHP version from the system + Returns: (latest_version, all_versions) + """ + try: + all_versions = PHPManager.findPHPVersions() + + if not all_versions: + return None, [] + + # Sort versions to get the latest + def version_sort_key(version): + try: + version_num = version.replace('PHP ', '').split('.') + major = int(version_num[0]) + minor = int(version_num[1]) if len(version_num) > 1 else 0 + return (major, minor) + except: + return (0, 0) + + sorted_versions = sorted(all_versions, key=version_sort_key, reverse=True) + latest_version = sorted_versions[0] + + return latest_version, all_versions + + except Exception as e: + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Error getting latest PHP version: {str(e)}') + return None, [] + + @staticmethod + def getRecommendedPHPVersion(): + """ + Get the recommended PHP version for new installations + Priority: 8.3 (recommended), 8.2, 8.4, 8.5, 8.1, 8.0, 7.4 + """ + try: + all_versions = PHPManager.findPHPVersions() + + if not all_versions: + return 'PHP 8.3' # Default recommendation + + # Priority order for recommendations + recommended_order = ['PHP 8.3', 'PHP 8.2', 'PHP 8.4', 'PHP 8.5', 'PHP 8.1', 'PHP 8.0', 'PHP 7.4'] + + for recommended in recommended_order: + if recommended in all_versions: + return recommended + + # If none of the recommended versions are available, return the latest + latest, _ = PHPManager.getLatestPHPVersion() + return latest if latest else 'PHP 8.3' + + except Exception as e: + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile(f'Error getting recommended PHP version: {str(e)}') + return 'PHP 8.3' + @staticmethod def FindPHPFPMPath(phpVersion): if phpVersion == "PHP 5.3": diff --git a/plogical/virtualHostUtilities.py b/plogical/virtualHostUtilities.py index d912a471b..985de1916 100644 --- a/plogical/virtualHostUtilities.py +++ b/plogical/virtualHostUtilities.py @@ -856,8 +856,50 @@ local_name %s { print("0, %s file is symlinked." % (fileName)) return 0 - numberOfTotalLines = int( - ProcessUtilities.outputExecutioner('wc -l %s' % (fileName), externalApp).split(" ")[0]) + # Improved wc -l parsing with better error handling + wc_output = ProcessUtilities.outputExecutioner('wc -l %s' % (fileName), externalApp) + + # Handle different wc output formats and potential errors + if wc_output and wc_output.strip(): + # Split by whitespace and take the first part that looks like a number + wc_parts = wc_output.strip().split() + numberOfTotalLines = 0 + + for part in wc_parts: + try: + numberOfTotalLines = int(part) + break + except ValueError: + continue + + # If no valid number found, try to extract from common wc error formats + if numberOfTotalLines == 0: + # Handle cases like "wc: filename: No such file or directory" + if "No such file or directory" in wc_output: + print("1,None") + return "1,None" + # Handle cases where wc returns just "wc:" or similar + if "wc:" in wc_output: + # Try to get line count using alternative method + try: + alt_output = ProcessUtilities.outputExecutioner('cat %s | wc -l' % (fileName), externalApp) + if alt_output and alt_output.strip(): + alt_parts = alt_output.strip().split() + for part in alt_parts: + try: + numberOfTotalLines = int(part) + break + except ValueError: + continue + except: + pass + + if numberOfTotalLines == 0: + print("1,None") + return "1,None" + else: + print("1,None") + return "1,None" if numberOfTotalLines < 25: data = ProcessUtilities.outputExecutioner('cat %s' % (fileName), externalApp) diff --git a/websiteFunctions/templates/websiteFunctions/error.html b/websiteFunctions/templates/websiteFunctions/error.html new file mode 100644 index 000000000..b7182c639 --- /dev/null +++ b/websiteFunctions/templates/websiteFunctions/error.html @@ -0,0 +1,62 @@ + + +
+ + +