AlkantarClanX12
Current Path : /usr/local/lsws/add-ons/webcachemgr/src/Panel/ |
Current File : //usr/local/lsws/add-ons/webcachemgr/src/Panel/CPanel.php |
<?php /** ****************************************** * LiteSpeed Web Server Cache Manager * * @author Michael Alegre * @copyright 2017-2023 LiteSpeed Technologies, Inc. * ******************************************* */ namespace Lsc\Wp\Panel; use Lsc\Wp\Logger; use Lsc\Wp\LSCMException; use Lsc\Wp\Util; use Lsc\Wp\WPInstall; class CPanel extends ControlPanel { /** * @var string */ const USER_PLUGIN_INSTALL_SCRIPT = '/usr/local/cpanel/whostmgr/docroot/cgi/lsws/res/ls_web_cache_mgr/install.sh'; /** * @deprecated 1.13.11 Split into paper_lantern and jupiter theme specific * constants. * @since 1.13.2 * @var string */ const USER_PLUGIN_DIR = '/usr/local/cpanel/base/frontend/paper_lantern/ls_web_cache_manager'; /** * @since 1.13.11 * @var string */ const THEME_JUPITER_USER_PLUGIN_DIR = '/usr/local/cpanel/base/frontend/jupiter/ls_web_cache_manager'; /** * @since 1.13.11 * @var string */ const THEME_PAPER_LANTERN_USER_PLUGIN_DIR = '/usr/local/cpanel/base/frontend/paper_lantern/ls_web_cache_manager'; /** * @deprecated 1.13.11 No longer used. * @var string */ const USER_PLUGIN_UNINSTALL_SCRIPT = self::USER_PLUGIN_DIR . '/uninstall.sh'; /** * @since 1.13.11 * @var string */ const USER_PLUGIN_RELATIVE_UNINSTALL_SCRIPT = 'uninstall.sh'; /** * @since 1.13.2 * @var string */ const USER_PLUGIN_BACKUP_DIR = '/tmp/lscp-plugin-tmp'; /** * @since 1.13.11 * @var string */ const USER_PLUGIN_RELATIVE_DATA_DIR = 'data'; /** * @deprecated 1.13.11 * @since 1.13.2 * @var string An old location for cPanel user-end plugin conf file. */ const USER_PLUGIN_CONF_OLD = self::USER_PLUGIN_DIR . '/lswcm.conf'; /** * @since 1.13.11 * @var string */ const USER_PLUGIN_RELATIVE_CONF_OLD = '/lswcm.conf'; /** * @since 1.13.11 * @var string */ const USER_PLUGIN_RELATIVE_CONF_OLD_2 = self::USER_PLUGIN_RELATIVE_DATA_DIR . '/lswcm.conf'; /** * @var string */ const USER_PLUGIN_CONF = '/usr/local/cpanel/3rdparty/ls_webcache_mgr/lswcm.conf'; /** * @var string */ const CPANEL_AUTOINSTALL_DISABLE_FLAG = '/usr/local/cpanel/whostmgr/docroot/cgi/lsws/cpanel_autoinstall_off'; /** * @var string */ const USER_PLUGIN_SETTING_VHOST_CACHE_ROOT = 'vhost_cache_root'; /** * @var string */ const USER_PLUGIN_SETTING_LSWS_DIR = 'lsws_dir'; /** * @deprecated 1.13.11 Never used. * @since 1.13.2 * @var string */ protected $cpanelPluginDataDir; /** * @deprecated 1.13.11 Never used. * @since 1.13.2 * @var string */ protected $cpanelPluginTplDir; /** * @deprecated 1.13.11 Never used. * @since 1.13.2 * @var string */ protected $cpanelPluginCustTransDir; /** * @deprecated 1.13.11 Never used. * @since 1.13.2 * @var string */ protected $tmpCpanelPluginDataDir; /** * @since 1.13.2 * @var string */ protected $tmpCpanelPluginTplDir; /** * @since 1.13.2 * @var string */ protected $tmpCpanelPluginCustTransDir; protected function __construct() { /** @noinspection PhpUnhandledExceptionInspection */ parent::__construct(); } /** * * @since 1.13.2 */ protected function init2() { $this->panelName = 'cPanel/WHM'; $this->defaultSvrCacheRoot = '/home/lscache/'; $this->tmpCpanelPluginTplDir = self::USER_PLUGIN_BACKUP_DIR . '/landing'; $this->tmpCpanelPluginCustTransDir = self::USER_PLUGIN_BACKUP_DIR . '/cust'; /** @noinspection PhpUnhandledExceptionInspection */ parent::init2(); } protected function initConfPaths() { $this->apacheConf = '/etc/apache2/conf.d/includes/pre_main_global.conf'; $this->apacheVHConf = '/etc/apache2/conf.d/userdata/lscache_vhosts.conf'; } /** * * @return string */ protected function serverCacheRootSearch() { if ( file_exists($this->apacheConf) ) { return $this->getCacheRootSetting($this->apacheConf); } return ''; } /** * * @return string */ protected function vhCacheRootSearch() { $apacheUserdataDir = dirname($this->apacheVHConf); if ( file_exists($apacheUserdataDir) ) { return $this->cacheRootSearch($apacheUserdataDir); } return ''; } /** * * @param array $file_contents * @param string $vhCacheRoot * * @return array */ protected function addVHCacheRootSection( array $file_contents, $vhCacheRoot = 'lscache' ) { array_unshift( $file_contents, "<IfModule LiteSpeed>\nCacheRoot $vhCacheRoot\n</IfModule>\n\n" ); return $file_contents; } /** * * @param string $vhConf * @param string $vhCacheRoot * * @throws LSCMException Thrown when virtual host conf directory cannot be * created. * @throws LSCMException Thrown when virtual host conf file cannot be * created. * @throws LSCMException Thrown indirectly by $this->log() call. * @throws LSCMException Thrown indirectly by $this->log() call. */ public function createVHConfAndSetCacheRoot( $vhConf, $vhCacheRoot = 'lscache' ) { $vhConfDir = dirname($vhConf); if ( !file_exists($vhConfDir) ) { if ( !mkdir($vhConfDir, 0755) ) { throw new LSCMException( "Failed to create directory $vhConfDir." ); } $this->log("Created directory $vhConfDir", Logger::L_DEBUG); } $vhConfFileCreated = ( file_put_contents( $vhConf, "<IfModule Litespeed>\nCacheRoot $vhCacheRoot\n</IfModule>" ) !== false ); if ( !$vhConfFileCreated ) { throw new LSCMException("Failed to create file $vhConf."); } $this->log("Created file $vhConf.", Logger::L_DEBUG); } /** * * @throws LSCMException Thrown indirectly by * self::UpdateCpanelPluginConf() call. */ public function applyVHConfChanges() { exec('/scripts/ensure_vhost_includes --all-users'); if ( file_exists(self::THEME_JUPITER_USER_PLUGIN_DIR) || file_exists(self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR) ) { self::UpdateCpanelPluginConf( self::USER_PLUGIN_SETTING_VHOST_CACHE_ROOT, $this->vhCacheRoot ); } } /** * Gets a list of found docroots and associated server names. * Only needed for scan logic. * * @throws LSCMException Thrown when an error is encountered by * preg_split() call on trimmed $line value. * @throws LSCMException Thrown indirectly by Logger::debug() call. * * @noinspection SpellCheckingInspection */ protected function prepareDocrootMap() { exec( 'grep -hro ' . '--exclude="cache" --exclude="main" --exclude="*.cache" ' . '"documentroot.*\|serveralias.*\|servername.*" ' . '/var/cpanel/userdata/*', $lines ); /** * [0]=docroot, [1]=serveraliases, [2]=servername, [3]=docroot, etc. * Not unique & not sorted. * * Example: * documentroot: /home/user1/finches * serveralias: finches.com mail.finches.com www.finches.com www.finches.user1.com cpanel.finches.com autodiscover.finches.com whm.finches.com webmail.finches.com webdisk.finches.com * servername: finches.user1.com * documentroot: /home/user1/public_html/dookoo * serveralias: www.dookoo.user1.com * servername: dookoo.user1.com * documentroot: /home/user1/public_html/doo/doo2 * serveralias: www.doo2.user1.com * servername: doo2.user1.com * documentroot: /home/user1/finches * serveralias: finches.com mail.finches.com www.finches.com www.finches.user1.com * servername: finches.user1.com */ $cur = ''; $docroots = array(); foreach ( $lines as $line ) { if ( $cur == '' ) { if ( strpos($line, 'documentroot:') === 0 ) { /** * 13 is strlen('documentroot:') */ $cur = trim(substr($line, 13)); if ( !isset($docroots[$cur]) ) { if ( is_dir($cur) ) { $docroots[$cur] = ''; } else { /** * bad entry ignore */ $cur = ''; } } } } elseif ( strpos($line, 'serveralias:') === 0 ) { /** * 12 is strlen('serveralias:') */ $docroots[$cur] .= substr($line, 12); } elseif ( strpos($line, 'servername:') === 0 ) { /** * 11 is strlen('servername:') */ $docroots[$cur] .= substr($line, 11); /** * looking for the next docroot */ $cur = ''; } else { Logger::debug("Unused line when preparing docroot map: $line."); } } $roots = array(); $servernames = array(); $index = 0; foreach ( $docroots as $docroot => $line ) { $names = preg_split('/\s+/', trim($line), -1, PREG_SPLIT_NO_EMPTY); if ( $names === false ) { throw new LSCMException( 'prepareDocrootMap(): Error encountered when calling ' . 'preg_split() on trimmed $line.' ); } $names = array_unique($names); $roots[$index] = $docroot; foreach ( $names as $n ) { $servernames[$n] = $index; } $index++; } $this->docRootMap = array( 'docroots' => $roots, 'names' => $servernames ); } /** * * @param WPInstall $wpInstall * * @return string */ public function getPhpBinary( WPInstall $wpInstall ) { /** * cPanel php wrapper should accurately detect the correct binary in * EA4 when EA4 only directive '--ea-reference-dir' is provided. */ return '/usr/local/bin/php ' . "--ea-reference-dir={$wpInstall->getPath()}/wp-admin " . $this->phpOptions; } /** * * @return bool */ public static function isCpanelPluginAutoInstallOn() { if ( file_exists(self::CPANEL_AUTOINSTALL_DISABLE_FLAG) ) { return false; } return true; } /** * * @return bool */ public static function turnOnCpanelPluginAutoInstall() { if ( !file_exists(self::CPANEL_AUTOINSTALL_DISABLE_FLAG) ) { return true; } return unlink(self::CPANEL_AUTOINSTALL_DISABLE_FLAG); } /** * * @return bool */ public static function turnOffCpanelPluginAutoInstall() { return touch(self::CPANEL_AUTOINSTALL_DISABLE_FLAG); } /** * * @return string * * @throws LSCMException Thrown when unable to find cPanel user-end plugin * installation script. * @throws LSCMException Thrown when failing to back up cPanel user-end * plugin data files. * @throws LSCMException Thrown indirectly by * self::backupCpanelPluginDataFiles() call. * @throws LSCMException Thrown indirectly by Logger::error() call. */ public function installCpanelPlugin() { if ( !file_exists(self::USER_PLUGIN_INSTALL_SCRIPT) ) { throw new LSCMException( 'Unable to find cPanel user-end plugin installation script.' . ' Please ensure that the LiteSpeed WHM plugin is already ' . 'installed.' ); } $existingInstall = ( file_exists(self::THEME_JUPITER_USER_PLUGIN_DIR) || file_exists(self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR) ); if ( $existingInstall ) { if ( !self::backupCpanelPluginDataFiles() ) { throw new LSCMException( 'Failed to backup cPanel user-end plugin data files. ' . 'Aborting install/update operation.' ); } exec(self::USER_PLUGIN_INSTALL_SCRIPT); if ( !self::restoreCpanelPluginDataFiles() ) { Logger::error( 'Failed to restore cPanel user-end plugin data files.' ); } } else { exec(self::USER_PLUGIN_INSTALL_SCRIPT); self::turnOnCpanelPluginAutoInstall(); } $this->updateCoreCpanelPluginConfSettings(); return ($existingInstall) ? 'update' : 'new'; } /** * * @since 1.13.2 * @since 1.13.2.2 Made function static. * @since 1.13.5.2 Removed optional param $oldLogic. * * @return bool * * @throws LSCMException Thrown when failing to create a temporary backup * directory. */ protected static function backupCpanelPluginDataFiles() { if ( file_exists(self::THEME_JUPITER_USER_PLUGIN_DIR) ) { $pluginDir = self::THEME_JUPITER_USER_PLUGIN_DIR; } elseif ( file_exists(self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR) ) { $pluginDir = self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR; } else { return false; } if ( file_exists(self::USER_PLUGIN_BACKUP_DIR) ) { Util::rrmdir(self::USER_PLUGIN_BACKUP_DIR); } if ( !mkdir(self::USER_PLUGIN_BACKUP_DIR, 0755) ) { throw new LSCMException( 'Failed to make temporary directory ' . self::USER_PLUGIN_BACKUP_DIR ); } /** * Move existing conf file (if needed), templates, and custom * translations to temp directory and remove default template dir to * prevent overwriting when moving back. */ $activeConfFile = self::getInstalledCpanelPluginActiveConfFileLocation($pluginDir); if ( $activeConfFile == '' || !file_exists($activeConfFile) ) { return false; } $backupCmds = ''; if ( $activeConfFile != self::USER_PLUGIN_CONF ) { $backupCmds .= "/bin/mv $activeConfFile " . self::USER_PLUGIN_BACKUP_DIR . '/;'; } $tmpCpanelPluginCustTransDir = self::USER_PLUGIN_BACKUP_DIR . '/cust'; $backupCmds .= '/bin/mv ' . "$pluginDir/landing " . self::USER_PLUGIN_BACKUP_DIR . '/;' . "/bin/rm -rf " . self::USER_PLUGIN_BACKUP_DIR . '/landing/default;' . '/bin/mv ' . "$pluginDir/lang/cust $tmpCpanelPluginCustTransDir;" . "/bin/rm -rf $tmpCpanelPluginCustTransDir/README"; exec($backupCmds); return true; } /** * * @since 1.13.2 * @since 1.13.2.2 Made function static. * @since 1.13.5.2 Removed optional param $oldLogic. * * @return bool */ protected static function restoreCpanelPluginDataFiles() { $pluginInstalls = array(); if ( file_exists(self::THEME_JUPITER_USER_PLUGIN_DIR) ) { $pluginInstalls[] = self::THEME_JUPITER_USER_PLUGIN_DIR; } if ( file_exists(self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR) ) { $pluginInstalls[] = self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR; } if ( !file_exists(self::USER_PLUGIN_BACKUP_DIR) || empty($pluginInstalls) ) { return false; } $tmpCpanelPluginConfFile = self::USER_PLUGIN_BACKUP_DIR . '/lswcm.conf'; foreach ( $pluginInstalls as $pluginInstall ) { $cpanelPluginLangDir = "$pluginInstall/lang"; if (!file_exists($cpanelPluginLangDir)) { mkdir($cpanelPluginLangDir, 0755); } if ( file_exists($tmpCpanelPluginConfFile) ) { $activeConfFile = self::getInstalledCpanelPluginActiveConfFileLocation( $pluginInstall ); if ($activeConfFile == '') { return false; } copy($tmpCpanelPluginConfFile, $activeConfFile); chmod($activeConfFile, 0644); } /** * Replace cPanel plugin templates, custom translations. */ exec( '/bin/cp -prf ' . self::USER_PLUGIN_BACKUP_DIR . "/landing $pluginInstall/;" . '/bin/cp -prf ' . self::USER_PLUGIN_BACKUP_DIR . "/cust $cpanelPluginLangDir/" ); } exec('/bin/rm -rf ' . self::USER_PLUGIN_BACKUP_DIR); return true; } /** * * @since 1.13.2.2 Made function static. * * @throws LSCMException Thrown when unable to find the uninstallation * script. */ public static function uninstallCpanelPlugin() { $jupiterUninstallFile = self::THEME_JUPITER_USER_PLUGIN_DIR . '/' . self::USER_PLUGIN_RELATIVE_UNINSTALL_SCRIPT; $paperLanternUninstallFile = self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR . '/' . self::USER_PLUGIN_RELATIVE_UNINSTALL_SCRIPT; if ( file_exists($jupiterUninstallFile) ) { $uninstallFile = $jupiterUninstallFile; } elseif ( file_exists($paperLanternUninstallFile) ) { $uninstallFile = $paperLanternUninstallFile; } else { throw new LSCMException( 'Unable to find cPanel user-end plugin uninstallation script. ' . 'Plugin may already be uninstalled.' ); } exec($uninstallFile); self::turnOffCpanelPluginAutoInstall(); } /** * Attempt to update core cPanel plugin settings used for basic plugin * operation to the currently discovered values. * * @since 1.13.2.2 * @since 1.13.5 Changed function visibility to public. * * @throws LSCMException Thrown indirectly by * self::UpdateCpanelPluginConf() call. * @throws LSCMException Thrown indirectly by $this->getVHCacheRoot() call. * @throws LSCMException Thrown indirectly by * self::UpdateCpanelPluginConf() call. */ public function updateCoreCpanelPluginConfSettings() { self::UpdateCpanelPluginConf( self::USER_PLUGIN_SETTING_LSWS_DIR, realpath(__DIR__ . '/../../../..') ); self::UpdateCpanelPluginConf( self::USER_PLUGIN_SETTING_VHOST_CACHE_ROOT, $this->getVHCacheRoot() ); } /** * * @since 1.13.2.2 Made function static. * * @param string $setting * @param mixed $value * * @throws LSCMException Thrown when unable to determine active cPanel * user-end plugin conf file location usually indicating that the * cPanel user-end plugin is not currently installed. * @throws LSCMException Thrown when unable to create cPanel user-end * plugin "data" directory for older versions of the cPanel user-end * plugin that require this directory. */ public static function UpdateCpanelPluginConf( $setting, $value ) { $pluginInstalls = array(); if ( file_exists(self::THEME_JUPITER_USER_PLUGIN_DIR) ) { $pluginInstalls[] = self::THEME_JUPITER_USER_PLUGIN_DIR; } else { $pluginInstalls[] = self::THEME_PAPER_LANTERN_USER_PLUGIN_DIR; } foreach ( $pluginInstalls as $pluginInstall ) { $activeConfFile = self::getInstalledCpanelPluginActiveConfFileLocation( $pluginInstall ); if ( $activeConfFile == '' ) { throw new LSCMException( 'Unable to determine active conf file location for cPanel ' . 'user-end plugin. cPanel user-end plugin is likely ' . 'not installed.' ); } if ( !file_exists($activeConfFile) ) { $oldConf = ''; if ( file_exists("$pluginInstall/" . self::USER_PLUGIN_RELATIVE_CONF_OLD_2) ) { $oldConf = "$pluginInstall/" . self::USER_PLUGIN_RELATIVE_CONF_OLD_2; } elseif ( file_exists("$pluginInstall/" . self::USER_PLUGIN_RELATIVE_CONF_OLD) ) { $oldConf = "$pluginInstall/" . self::USER_PLUGIN_RELATIVE_CONF_OLD; } if ( $oldConf != '' ) { $dataDir = "$pluginInstall/" . self::USER_PLUGIN_RELATIVE_DATA_DIR; if ( $activeConfFile == "$pluginInstall/" . self::USER_PLUGIN_RELATIVE_CONF_OLD_2 && !file_exists($dataDir) && !mkdir($dataDir) ) { throw new LSCMException( "Failed to create directory $dataDir." ); } copy($oldConf, $activeConfFile); } } if ( file_exists($activeConfFile) ) { chmod($activeConfFile, 0644); switch ( $setting ) { case self::USER_PLUGIN_SETTING_LSWS_DIR: $pattern = '/LSWS_HOME_DIR = ".*"/'; $replacement = "LSWS_HOME_DIR = \"$value\""; break; case self::USER_PLUGIN_SETTING_VHOST_CACHE_ROOT: $pattern = '/VHOST_CACHE_ROOT = ".*"/'; $replacement = "VHOST_CACHE_ROOT = \"$value\""; break; default: return; } $content = file_get_contents($activeConfFile); if ( preg_match($pattern, $content) ) { file_put_contents( $activeConfFile, preg_replace($pattern, $replacement, $content) ); } else { file_put_contents( $activeConfFile, $replacement, FILE_APPEND ); } } } } /** * * @since 1.13.11 * * @param string $pluginDir * * @return string */ protected static function getInstalledCpanelPluginActiveConfFileLocation( $pluginDir ) { $versionFile = "$pluginDir/VERSION"; if ( file_exists($versionFile) ) { $verGreaterThan2_1_2_2 = Util::betterVersionCompare( file_get_contents($versionFile), '2.1.2.2', '>' ); if ( $verGreaterThan2_1_2_2 ) { return self::USER_PLUGIN_CONF; } } if ( file_exists("$pluginDir/" . self::USER_PLUGIN_RELATIVE_DATA_DIR) ) { return "$pluginDir/" . self::USER_PLUGIN_RELATIVE_CONF_OLD_2; } if ( file_exists($pluginDir) ) { return "$pluginDir/" . self::USER_PLUGIN_RELATIVE_CONF_OLD; } return ''; } }