HEX
Server: LiteSpeed
System: Linux php-prod-1.spaceapp.ru 5.15.0-157-generic #167-Ubuntu SMP Wed Sep 17 21:35:53 UTC 2025 x86_64
User: xnsbb3110 (1041)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: //usr/local/CyberCP/managePHP/phpManager.py
import os.path

from plogical.processUtilities import ProcessUtilities
import json
import re
from django.shortcuts import HttpResponse
from random import randint
from .models import *
from xml.etree import ElementTree

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']

        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)

                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 versions in findPHPVersions: {finalPHPVersions}')

            # 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']

    @staticmethod
    def findApachePHPVersions():
        # 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']

        try:

            # Run the shell command and capture the output
            from ApachController.ApacheController import ApacheController as ApachController
            result = ProcessUtilities.outputExecutioner(f'ls -la {ApachController.phpBasepath}')

            if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8:

                # Get the lines containing 'lsphp' in the output
                lsphp_lines = [line for line in result.split('\n') if 'php' in line]

                if os.path.exists(ProcessUtilities.debugPath):
                    from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
                    logging.writeToFile(f'Found PHP lines in findApachePHPVersions: {lsphp_lines}')

                # Extract the version from the lines and format it as 'PHP x.y'
                # Extract and format PHP versions
                php_versions = []
                for entry in lsphp_lines:
                    # Find substring starting with 'php' and extract the version part
                    version = entry.split('php')[1]
                    # Format version as PHP X.Y
                    formatted_version = f"PHP {version[0]}.{version[1]}"
                    php_versions.append(formatted_version)
            else:

                lsphp_lines = [line for line in result.split('\n')]

                if os.path.exists(ProcessUtilities.debugPath):
                    from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
                    logging.writeToFile(f'Found PHP lines in findApachePHPVersions: {lsphp_lines}')

                # Extract the version from the lines and format it as 'PHP x.y'
                # Extract and format PHP versions
                php_versions = []
                for entry in lsphp_lines:
                    # Find substring starting with 'php' and extract the version part
                    try:
                        version = entry.split('.')
                        # Format version as PHP X.Y
                        formatted_version = f"PHP {version[-2][-1]}.{version[-1]}"
                        if formatted_version != 'PHP  .':
                            php_versions.append(formatted_version)
                    except:
                        pass




            if os.path.exists(ProcessUtilities.debugPath):
                from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
                logging.writeToFile(f'Found PHP versions in findApachePHPVersions: {php_versions}')

            # Now php_versions contains the formatted PHP versions
            return php_versions
        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']

    @staticmethod
    def getPHPString(phpVersion):
        # Ex: "PHP 5.3" type string, return Ex: "53" type string
        phpVersion = phpVersion.split()
        php = phpVersion[1].replace(".", "")

        return php

    @staticmethod
    def FindPHPFPMPath(phpVersion):
        if phpVersion == "PHP 5.3":
            return "/opt/remi/php54/root/etc/php.ini"
        elif phpVersion == "PHP 5.4":
            return "/opt/remi/php54/root/etc/php.ini"
        elif phpVersion == "PHP 5.5":
            return "/opt/remi/php55/root/etc/php.ini"
        elif phpVersion == "PHP 5.6":
            return "/etc/opt/remi/php56/php.ini"
        elif phpVersion == "PHP 7.0":
            return "/etc/opt/remi/php70/php.ini"
        elif phpVersion == "PHP 7.1":
            return "/etc/opt/remi/php71/php.ini"
        elif phpVersion == "PHP 7.2":
            return "/etc/opt/remi/php72/php.ini"
        elif phpVersion == "PHP 7.3":
            return "/etc/opt/remi/php73/php.ini"


    @staticmethod
    def getCurrentPHPConfig(phpVersion):
        allow_url_fopen = "0"
        display_errors = "0"
        file_uploads = "0"
        allow_url_include = "0"
        memory_limit = ""
        max_execution_time = ""
        upload_max_filesize = ""
        max_input_time = ""

        command = "cat " + PHPManager.FindPHPFPMPath(phpVersion)

        data = ProcessUtilities.outputExecutioner(command).split('\n')

        for items in data:
            if items.find("allow_url_fopen") > -1 and items.find("=") > -1:
                if items.find("On") > -1:
                    allow_url_fopen = "1"
            if items.find("display_errors") > -1 and items.find("=") > -1:
                if items.find("On") > -1:
                    display_errors = "1"
            if items.find("file_uploads") > -1 and items.find("=") > -1:
                if items.find("On") > -1:
                    file_uploads = "1"
            if items.find("allow_url_include") > -1 and items.find("=") > -1:
                if items.find("On") > -1:
                    allow_url_include = "1"
            if items.find("memory_limit") > -1 and items.find("=") > -1:
                memory_limit = re.findall(r"[A-Za-z0-9_]+", items)[1]
            if items.find("max_execution_time") > -1 and items.find("=") > -1:
                max_execution_time = re.findall(r"[A-Za-z0-9_]+", items)[1]
            if items.find("upload_max_filesize") > -1 and items.find("=") > -1:
                upload_max_filesize = re.findall(r"[A-Za-z0-9_]+", items)[1]
            if items.find("max_input_time") > -1 and items.find("=") > -1:
                max_input_time = re.findall(r"[A-Za-z0-9_]+", items)[1]
            if items.find("post_max_size") > -1 and items.find("=") > -1:
                post_max_size = re.findall(r"[A-Za-z0-9_]+", items)[1]

        final_dic = {'fetchStatus': 1,
                     'allow_url_fopen': allow_url_fopen,
                     'display_errors': display_errors,
                     'file_uploads': file_uploads,
                     'allow_url_include': allow_url_include,
                     'memory_limit': memory_limit,
                     'max_execution_time': max_execution_time,
                     'upload_max_filesize': upload_max_filesize,
                     'max_input_time': max_input_time,
                     'post_max_size': post_max_size,
                     'status': 1}

        final_json = json.dumps(final_dic)

        return HttpResponse(final_json)

    @staticmethod
    def savePHPConfigBasic(data):
        phpVersion = data['phpVersion']
        allow_url_fopen = data['allow_url_fopen']
        display_errors = data['display_errors']
        file_uploads = data['file_uploads']
        allow_url_include = data['allow_url_include']
        memory_limit = data['memory_limit']
        max_execution_time = data['max_execution_time']
        upload_max_filesize = data['upload_max_filesize']
        max_input_time = data['max_input_time']
        post_max_size = data['post_max_size']

        if allow_url_fopen:
            allow_url_fopen = "allow_url_fopen = On"
        else:
            allow_url_fopen = "allow_url_fopen = Off"

        if display_errors:
            display_errors = "display_errors = On"
        else:
            display_errors = "display_errors = Off"

        if file_uploads:
            file_uploads = "file_uploads = On"
        else:
            file_uploads = "file_uploads = Off"

        if allow_url_include:
            allow_url_include = "allow_url_include = On"
        else:
            allow_url_include = "allow_url_include = Off"

        path = PHPManager.FindPHPFPMPath(phpVersion)
        command = "cat " + path
        data = ProcessUtilities.outputExecutioner(command).splitlines()

        tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))

        writeToFile = open(tempStatusPath, 'w')

        # Track which directives we've found and replaced
        found_directives = {
            'allow_url_fopen': False,
            'display_errors': False,
            'file_uploads': False,
            'allow_url_include': False,
            'memory_limit': False,
            'max_execution_time': False,
            'upload_max_filesize': False,
            'max_input_time': False,
            'post_max_size': False
        }

        for items in data:
            if items.find("allow_url_fopen") > -1 and items.find("=") > -1:
                writeToFile.writelines(allow_url_fopen + "\n")
                found_directives['allow_url_fopen'] = True
            elif items.find("display_errors") > -1 and items.find("=") > -1:
                writeToFile.writelines(display_errors + "\n")
                found_directives['display_errors'] = True
            elif items.find("file_uploads") > -1 and items.find("=") > -1 and not items.find(
                    "max_file_uploads") > -1:
                writeToFile.writelines(file_uploads + "\n")
                found_directives['file_uploads'] = True
            elif items.find("allow_url_include") > -1 and items.find("=") > -1:
                writeToFile.writelines(allow_url_include + "\n")
                found_directives['allow_url_include'] = True
            elif items.find("memory_limit") > -1 and items.find("=") > -1:
                writeToFile.writelines("memory_limit = " + memory_limit + "\n")
                found_directives['memory_limit'] = True
            elif items.find("max_execution_time") > -1 and items.find("=") > -1:
                writeToFile.writelines("max_execution_time = " + max_execution_time + "\n")
                found_directives['max_execution_time'] = True
            elif items.find("upload_max_filesize") > -1 and items.find("=") > -1:
                writeToFile.writelines("upload_max_filesize = " + upload_max_filesize + "\n")
                found_directives['upload_max_filesize'] = True
            elif items.find("max_input_time") > -1 and items.find("=") > -1:
                writeToFile.writelines("max_input_time = " + max_input_time + "\n")
                found_directives['max_input_time'] = True
            elif items.find("post_max_size") > -1 and items.find("=") > -1:
                writeToFile.writelines("post_max_size = " + post_max_size + "\n")
                found_directives['post_max_size'] = True
            else:
                writeToFile.writelines(items + '\n')

        # Add any missing directives at the end of the file
        missing_directives = []
        if not found_directives['allow_url_fopen']:
            missing_directives.append(allow_url_fopen)
        if not found_directives['display_errors']:
            missing_directives.append(display_errors)
        if not found_directives['file_uploads']:
            missing_directives.append(file_uploads)
        if not found_directives['allow_url_include']:
            missing_directives.append(allow_url_include)
        if not found_directives['memory_limit']:
            missing_directives.append("memory_limit = " + memory_limit)
        if not found_directives['max_execution_time']:
            missing_directives.append("max_execution_time = " + max_execution_time)
        if not found_directives['upload_max_filesize']:
            missing_directives.append("upload_max_filesize = " + upload_max_filesize)
        if not found_directives['max_input_time']:
            missing_directives.append("max_input_time = " + max_input_time)
        if not found_directives['post_max_size']:
            missing_directives.append("post_max_size = " + post_max_size)

        if missing_directives:
            writeToFile.writelines("\n; Added by CyberPanel PHP Config Manager\n")
            for directive in missing_directives:
                writeToFile.writelines(directive + "\n")

        writeToFile.close()

        command = "mv %s %s" % (tempStatusPath, path)
        ProcessUtilities.executioner(command)

        php = PHPManager.getPHPString(phpVersion)

        command = "systemctl stop php%s-php-fpm" % (php)
        ProcessUtilities.executioner(command)

        command = "systemctl start php%s-php-fpm" % (php)
        ProcessUtilities.executioner(command)

        final_dic = {'status': 1}
        final_json = json.dumps(final_dic)
        return HttpResponse(final_json)

    @staticmethod
    def fetchPHPSettingsAdvance(phpVersion):
        command = "cat " + PHPManager.FindPHPFPMPath(phpVersion)
        data = ProcessUtilities.outputExecutioner(command)
        final_dic = {'fetchStatus': 1,
                     'configData': data,
                     'status': 1}

        final_json = json.dumps(final_dic)

        return HttpResponse(final_json)

    @staticmethod
    def savePHPConfigAdvance(data):
        phpVersion = data['phpVersion']
        configData = data['configData']

        path = PHPManager.FindPHPFPMPath(phpVersion)

        tempStatusPath = "/home/cyberpanel/" + str(randint(1000, 9999))

        writeToFile = open(tempStatusPath, 'w')
        writeToFile.write(configData)
        writeToFile.close()

        command = "mv %s %s" % (tempStatusPath, path)
        ProcessUtilities.executioner(command)

        php = PHPManager.getPHPString(phpVersion)

        command = "systemctl stop php%s-php-fpm" % (php)
        ProcessUtilities.executioner(command)

        command = "systemctl start php%s-php-fpm" % (php)
        ProcessUtilities.executioner(command)

        final_dic = {'status': 1}
        final_json = json.dumps(final_dic)
        return HttpResponse(final_json)

    @staticmethod
    def fetchPHPExtensions(data):

        if ApachePHP.objects.all().count() == 0:
            phpfilePath = '/usr/local/CyberCP/ApachController/phpApache.xml'

            for items in ['54', '55', '56', '70', '71', '72', '73']:
                phpvers = ApachePHP(phpVers='php' + items)
                phpvers.save()

                php = ElementTree.parse(phpfilePath)
                phpExtensions = php.findall('extension')

                for extension in phpExtensions:
                    extensionName = extension.find('extensionName').text % (items)
                    extensionDescription = extension.find('extensionDescription').text
                    status = int(extension.find('status').text)

                    phpExtension = installedPackagesApache(phpVers=phpvers,
                                                     extensionName=extensionName,
                                                     description=extensionDescription,
                                                     status=status)

                    phpExtension.save()

        phpVers = "php" + PHPManager.getPHPString(data['phpVersion'])

        phpVersion = ApachePHP.objects.get(phpVers=phpVers)

        records = phpVersion.installedpackagesapache_set.all()

        json_data = "["
        checker = 0

        for items in records:

            if items.status == 0:
                status = "Not-Installed"
            else:
                status = "Installed"

            dic = {'id': items.id,
                   'phpVers': items.phpVers.phpVers,
                   'extensionName': items.extensionName,
                   'description': items.description,
                   'status': status
                   }

            if checker == 0:
                json_data = json_data + json.dumps(dic)
                checker = 1
            else:
                json_data = json_data + ',' + json.dumps(dic)

        json_data = json_data + ']'
        final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
        return HttpResponse(final_json)