Viewing File: /usr/local/cpanel/base/frontend/jupiter/ls_web_cache_manager/core/Lsc/UserWPInstall.php

<?php

/** *********************************************
 * LiteSpeed Web Cache Management Plugin for cPanel
 *
 * @author    Michael Alegre
 * @copyright 2018-2025 LiteSpeed Technologies, Inc.
 * *******************************************
 */

namespace LsUserPanel\Lsc;

use LsUserPanel\CPanelWrapper;
use LsUserPanel\Lsc\Context\UserContext;
use LsUserPanel\Lsc\Panel\UserControlPanel;

class UserWPInstall
{

    /**
     * @var int
     */
    const ST_PLUGIN_ACTIVE = 1;

    /**
     * @var int
     */
    const ST_PLUGIN_INACTIVE = 2;

    /**
     * @var int
     */
    const ST_LSC_ADVCACHE_DEFINED = 4;

    /**
     * @var int
     */
    const ST_FLAGGED = 8;

    /**
     * @var int
     */
    const ST_ERR_SITEURL = 16;

    /**
     * @var int
     */
    const ST_ERR_DOCROOT = 32;

    /**
     * @var int
     */
    const ST_ERR_EXECMD = 64;

    /**
     * @var int
     */
    const ST_ERR_TIMEOUT = 128;

    /**
     * @var int
     */
    const ST_ERR_EXECMD_DB = 256;

    /**
     * @var int
     */
    const ST_ERR_WPCONFIG = 1024;

    /**
     * @var int
     */
    const ST_ERR_REMOVE = 2048;

    /**
     * @var string
     */
    const FLD_STATUS = 'status';

    /**
     * @var string
     */
    const FLD_DOCROOT = 'docroot';

    /**
     * @var string
     */
    const FLD_SERVERNAME = 'server_name';

    /**
     * @var string
     */
    const FLD_SITEURL = 'site_url';

    /**
     * @var string
     */
    const FLAG_FILE = '.litespeed_flag';

    /**
     * @var string
     */
    const FLAG_NEW_LSCWP = '.lscm_new_lscwp';

    /**
     * @var string
     */
    private $path;

    /**
     * @var array
     */
    private $data;

    /**
     * @var null|string
     */
    private $phpBinary = null;

    /**
     * @var bool
     */
    private $changed = false;

    /**
     * @var bool
     */
    private $refreshed = false;

    /**
     * @var null|string
     */
    private $wpConfigFile = '';

    /**
     * @var int
     */
    private $cmdStatus = 0;

    /**
     * @var string
     */
    private $cmdMsg = '';

    /**
     *
     * @param string $path
     */
    public function __construct( $path )
    {
        $this->init($path);
    }

    /**
     *
     * @param string $path
     */
    private function init( $path )
    {
        if ( ($realPath = realpath($path)) !== false ) {
            $this->path = $realPath;
        }
        else {
            $this->path = $path;
        }

        $this->data = array(
            self::FLD_STATUS     => 0,
            self::FLD_DOCROOT    => null,
            self::FLD_SERVERNAME => null,
            self::FLD_SITEURL    => null
        );
    }

    /**
     *
     * @return string
     */
    public function __toString()
    {
        return sprintf(
            "%s (status=%d docroot=%s siteurl=%s)",
            $this->path,
            $this->data[self::FLD_STATUS],
            $this->data[self::FLD_DOCROOT],
            UserUtil::tryIdnToUtf8($this->data[self::FLD_SITEURL])
        );
    }

    /**
     *
     * @param int $status
     *
     * @return bool
     */
    public function setStatus( $status )
    {
        return $this->setData(self::FLD_STATUS, $status);
    }

    /**
     *
     * @return int
     */
    public function getStatus()
    {
        return $this->getData(self::FLD_STATUS);
    }

    /**
     *
     * @param string $field
     *
     * @return mixed|null
     */
    public function getData( $field = '' )
    {
        if ( !$field ) {
            return $this->data;
        }

        if ( !isset($this->data[$field]) ) {
            /**
             * Error out
             */
            return null;
        }

        return $this->data[$field];
    }

    /**
     *
     * @param string $field
     * @param mixed  $value
     *
     * @return bool
     */
    private function setData( $field, $value )
    {
        if ( $this->data[$field] === $value ) {
            return false;
        }

        $this->changed      = true;
        $this->data[$field] = $value;

        return true;
    }

    /**
     * Calling from unserialized data.
     *
     * @param array $data
     */
    public function initData( $data )
    {
        $this->data = $data;
    }

    /**
     *
     * @return string
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     *
     * @return bool
     */
    public function shouldRemove()
    {
        return (bool)($this->getStatus() & self::ST_ERR_REMOVE);
    }

    /**
     *
     * @since 2.1
     *
     * @return bool
     */
    public function isLscwpEnabled()
    {
        return (bool)($this->getStatus() & self::ST_PLUGIN_ACTIVE);
    }

    /**
     *
     * @return bool
     */
    public function hasNewLscwpFlagFile()
    {
        return file_exists("$this->path/" . self::FLAG_NEW_LSCWP);
    }

    /**
     *
     * @return bool
     *
     * @throws UserLSCMException  Thrown indirectly by UserLogger::addUiMsg()
     *     call.
     * @throws UserLSCMException  Thrown indirectly by UserLogger::logMsg()
     *     call.
     */
    public function hasValidPath()
    {
        if ( !is_dir($this->path) || !is_dir("$this->path/wp-admin") ) {
            $this->setStatusBit(self::ST_ERR_REMOVE);

            UserLogger::addUiMsg(
                "{$this->getPath()} - "
                    . _(
                        'Installation could not be found and has been removed '
                            . 'from Cache Manager list.'
                    ),
                UserLogger::UI_ERR
            );
            UserLogger::logMsg(
                "{$this->getPath()} - Installation could not be found and has "
                    . 'been removed from Cache Manager list.',
                UserLogger::L_NOTICE
            );

            return false;
        }

        if ( $this->getWpConfigFile() == null ) {
            $this->setStatusBit(self::ST_ERR_WPCONFIG);
            return false;
        }

        return true;
    }

    /**
     * Set the provided status bit.
     *
     * @param int $bit
     */
    public function setStatusBit( $bit )
    {
        $this->setStatus(($this->getStatus() | $bit));
    }

    /**
     * Unset the provided status bit.
     *
     * @param int $bit
     */
    public function unsetStatusBit( $bit )
    {
        $this->setStatus(($this->getStatus() & ~$bit));
    }

    /**
     *
     * @deprecated 2.1  Deprecated to avoid confusion with $this->cmdStatus and
     *     $this->cmdMsg related functions. Use $this->setStatus() instead.
     *
     * @param int $newStatus
     */
    public function updateCommandStatus( $newStatus )
    {
        $this->setData(self::FLD_STATUS, $newStatus);
    }

    /**
     *
     * @return null|string
     */
    public function getWpConfigFile()
    {
        if ( $this->wpConfigFile === '' ) {
            $file = "$this->path/wp-config.php";

            if ( !file_exists($file) ) {
                /**
                 *  check parent dir
                 */
                $parentDir = dirname($this->path);
                $file      = "$parentDir/wp-config.php";

                if ( !file_exists($file)
                        || file_exists("$parentDir/wp-settings.php") ) {

                    /**
                     * If wp-config moved up, in same dir should NOT have
                     * wp-settings
                     */
                    $file = null;
                }
            }

            $this->wpConfigFile = $file;
        }

        return $this->wpConfigFile;
    }

    /**
     *
     * @deprecated 2.1  Use populateDataFromUrl() instead.
     *
     * @param string $siteUrl
     *
     * @return bool
     *
     * @throws UserLSCMException  Thrown indirectly by
     *     $this->populateDataFromUrl() call.
     */
    public function setSiteUrl( $siteUrl )
    {
        return $this->populateDataFromUrl($siteUrl);
    }

    /**
     * Takes a WordPress site URL and uses it to populate serverName, siteUrl,
     * and docRoot data. If a matching docRoot cannot be found using the
     * serverName, the installation will be flagged and an ST_ERR_DOCROOT status
     * set.
     *
     * @param string $siteUrl
     *
     * @return bool
     *
     * @throws UserLSCMException  Thrown indirectly by
     *     UserControlPanel::getInstance() call.
     * @throws UserLSCMException  Thrown indirectly by
     *     UserControlPanel::getInstance()->mapDocRoot() call.
     * @throws UserLSCMException  Thrown indirectly by $this->addUserFlagFile()
     *     call.
     * @throws UserLSCMException  Thrown indirectly by UserLogger::error() call.
     */
    public function populateDataFromUrl( $siteUrl )
    {
        if ( preg_match('#^https?://#', $siteUrl) ) {
            $parseSafeSiteUrl = $siteUrl;
        }
        else {
            $parseSafeSiteUrl = "http://$siteUrl";
        }

        $info = parse_url($parseSafeSiteUrl);

        $serverName = UserUtil::tryIdnToAscii($info['host']);

        $this->setData(self::FLD_SERVERNAME, $serverName);

        $siteUrlTrim = $serverName;

        if ( isset($info['path']) ) {
            $siteUrlTrim .= $info['path'];
        }

        $this->setData(self::FLD_SITEURL, $siteUrlTrim);

        $docRoot = UserControlPanel::getInstance()->mapDocRoot($serverName);
        $this->setData(self::FLD_DOCROOT, $docRoot);

        if ( $docRoot === null ) {
            $this->setStatus(self::ST_ERR_DOCROOT);
            $this->addUserFlagFile();

            $this->setCmdStatusAndMsg(
                UserUserCommand::EXIT_ERROR,
                "$this->path - "
                    . sprintf(
                        _(
                            'Could not find matching document root for %1$s '
                                . 'siteurl/servername %2$s.'
                        ),
                        'WP',
                        $serverName
                    )
            );
            UserLogger::error(
                "$this->path - Could not find matching document root for WP "
                    . "siteurl/servername $serverName."
            );

            return false;
        }

        return true;
    }

    /**
     * Adds the flag file to an installation.
     *
     * @return bool  True when install has a flag file created/already.
     *
     * @throws UserLSCMException  Thrown indirectly by
     *     UserContext::getFlagFileContent() call.
     */
    public function addUserFlagFile()
    {
        $file = "$this->path/" . self::FLAG_FILE;

        if ( !file_exists($file) ) {
            $flagFileCreated =
                file_put_contents($file, UserContext::getFlagFileContent());

            if ( !$flagFileCreated ) {
                return false;
            }
        }

        $this->setStatusBit(self::ST_FLAGGED);
        return true;
    }

    /**
     *
     * @return bool
     */
    public function removeFlagFile()
    {
        $file = "$this->path/" . self::FLAG_FILE;

        if ( file_exists($file) && !unlink($file) ) {
            return false;
        }

        $this->unsetStatusBit(self::ST_FLAGGED);
        return true;
    }

    /**
     * Remove "In Progress" flag file to indicate that a WPInstall action has
     * been completed.
     *
     * @return bool
     */
    public function removeNewLscwpFlagFile()
    {
        $cpanel = CPanelWrapper::getCpanelObj();

        $result = $cpanel->uapi(
            'lsws',
            'removeNewLscwpFlagFile',
            array( 'path' => $this->path )
        );

        return (bool)$result['cpanelresult']['result']['data']['result'];
    }

    /**
     *
     * @param bool $forced
     *
     * @return int
     *
     * @throws UserLSCMException  Thrown indirectly by UserUserCommand::issue()
     *     call.
     */
    public function refreshStatus( $forced = false )
    {
        if ( !$this->refreshed || $forced ) {
            $this->refreshed = true;
            UserUserCommand::issue(UserUserCommand::CMD_STATUS, $this);
        }

        return $this->getData(self::FLD_STATUS);
    }

    /**
     *
     * @param null|int $status
     *
     * @return bool
     */
    public function hasFatalError( $status = null )
    {
        if ( $status === null ) {
            $status = $this->getData(self::FLD_STATUS);
        }

        $errMask = (
            self::ST_ERR_EXECMD
                | self::ST_ERR_EXECMD_DB
                | self::ST_ERR_TIMEOUT
                | self::ST_ERR_SITEURL
                | self::ST_ERR_DOCROOT
                | self::ST_ERR_WPCONFIG
        );

        return (($status & $errMask) > 0);
    }

    /**
     *
     * @return string
     *
     * @throws UserLSCMException  Thrown indirectly by
     *     UserControlPanel::getInstance() call.
     */
    public function getPhpBinary()
    {
        if ( $this->phpBinary == null ) {
            $this->phpBinary =
                UserControlPanel::getInstance()->getPhpBinary($this);
        }

        return $this->phpBinary;
    }

    /**
     *
     * @return int
     */
    public function getCmdStatus()
    {
        return $this->cmdStatus;
    }

    /**
     *
     * @return string
     */
    public function getCmdMsg()
    {
        return $this->cmdMsg;
    }

    /**
     *
     * @param int    $status
     * @param string $msg
     */
    public function setCmdStatusAndMsg( $status, $msg )
    {
        $this->cmdStatus = $status;
        $this->cmdMsg    = $msg;
    }

}
Back to Directory File Manager