????
Current Path : /usr/local/lsws/add-ons/webcachemgr/src/ |
Current File : //usr/local/lsws/add-ons/webcachemgr/src/Util.php |
<?php /** ********************************************* * LiteSpeed Web Server Cache Manager * * @author Michael Alegre * @copyright 2018-2023 LiteSpeed Technologies, Inc. * ******************************************* */ namespace Lsc\Wp; use ZipArchive; class Util { /** * * @param string $tag * * @return string */ public static function get_request_var( $tag ) { if ( isset($_REQUEST[$tag]) ) { return trim($_REQUEST[$tag]); } /** * Request var not found in $_REQUEST, try checking POST and * QUERY_STRING environment variables. */ if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) { $querystring = urldecode(getenv('POST')); } else { $querystring = urldecode(getenv('QUERY_STRING')); } if ( $querystring != '' && preg_match("/(?:^|\?|&)$tag=([^&]+)/", $querystring, $m) ) { return trim($m[1]); } return null; } /** * * @param string $tag * * @return array */ public static function get_request_list( $tag ) { $varValue = null; if ( isset($_REQUEST[$tag]) ) { $varValue = $_REQUEST[$tag]; } else { /** * Request var not found in $_REQUEST, try checking POST and * QUERY_STRING environment variables. */ if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) { $querystring = urldecode(getenv('POST')); } else { $querystring = urldecode(getenv('QUERY_STRING')); } if ( $querystring != '' && preg_match_all("/(?:^|\?|&)$tag\[]=([^&]+)/", $querystring, $m) ) { $varValue = $m[1]; } } return (is_array($varValue)) ? $varValue : null; } /** * * @throws LSCMException Thrown indirectly by Logger::info() call. */ public static function restartLsws() { Logger::info('Performing a Graceful Restart to apply changes...'); /** * @noinspection PhpMethodParametersCountMismatchInspection Suppress * for PHP 5.x. */ if ( php_uname('s') == 'FreeBSD' ) { $lswsCtl = '/usr/local/etc/rc.d/lsws.sh'; } else { $lswsCtl = '/sbin/service lsws'; } exec("$lswsCtl restart"); } /** * @since 2.1.15 * * @param int $startTime * @param int $timeout * * @return bool */ public static function timedOut( $startTime, $timeout ) { return ((time() - $startTime) > $timeout); } /** * This function is used to get the file owner by name. Useful in cases * where UID is not accepted or setting a files group to match its owner * (It is not safe to assume UID == GID or GID exists for username 'x'). * * @since 2.2.0 * * @param string $filepath * * @return array Keys are id, name, group_id */ public static function populateOwnerInfo( $filepath ) { clearstatcache(); $ownerID = fileowner($filepath); $ownerInfo = posix_getpwuid($ownerID); return array( 'user_id' => $ownerID, 'user_name' => $ownerInfo['name'], 'group_id' => filegroup($filepath) ); } /** * * @param string $file * @param string $owner * @param string $group */ public static function changeUserGroup( $file, $owner, $group ) { chown($file, $owner); chgrp($file, $group); } /** * Set file permissions of $file2 to match those of $file1. * * @since 2.2.0 * * @param string $file1 * @param string $file2 */ public static function matchPermissions( $file1, $file2 ) { /** * convert fileperms() returned dec to oct */ chmod($file2, (fileperms($file1) & 0777)); } /** * * @since 1.14.3 * * @param string $url * @param bool $headerOnly * * @return string */ public static function getUrlContentsUsingFileGetContents( $url, $headerOnly = false ) { if ( ini_get('allow_url_fopen') ) { /** * silence warning when OpenSSL missing while getting LSCWP ver * file. */ $url_content = @file_get_contents($url); if ( $url_content !== false ) { if ( $headerOnly ) { return implode("\n", $http_response_header); } return $url_content; } } return ''; } /** * * @since 1.14.3 * * @param string $url * @param bool $headerOnly * * @return string */ public static function getUrlContentsUsingPhpCurl( $url, $headerOnly = false ) { if ( function_exists('curl_version') ) { $ch = curl_init(); curl_setopt_array( $ch, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => $headerOnly, CURLOPT_NOBODY => $headerOnly, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 ) ); $url_content = curl_exec($ch); curl_close($ch); if ( $url_content !== false ) { return $url_content; } } return ''; } /** * * @since 1.14.3 * * @param string $url * @param string $headerOnly * * @return string */ public static function getUrlContentsUsingExecCurl( $url, $headerOnly = false ) { $cmd = 'curl -s'; if ( $headerOnly ) { $cmd .= ' -I'; } exec("$cmd $url", $output, $ret); if ( $ret === 0 ) { return implode("\n", $output); } return ''; } /** * * @param string $url * @param bool $headerOnly * * @return string */ public static function get_url_contents( $url, $headerOnly = false ) { $content = self::getUrlContentsUsingFileGetContents($url, $headerOnly); if ( $content != '' ) { return $content; } $content = self::getUrlContentsUsingPhpCurl($url, $headerOnly); if ( $content != '' ) { return $content; } return self::getUrlContentsUsingExecCurl($url, $headerOnly); } /** * * @param string $dir * * @return false|string */ public static function DirectoryMd5( $dir ) { if ( !is_dir($dir) ) { return false; } $fileMd5s = array(); $d = dir($dir); while ( ($entry = $d->read()) !== false ) { if ( $entry != '.' && $entry != '..' ) { $currEntry = "$dir/$entry"; if ( is_dir($currEntry) ) { $fileMd5s[] = self::DirectoryMd5($currEntry); } else { $fileMd5s[] = md5_file($currEntry); } } } $d->close(); return md5(implode('', $fileMd5s)); } /** * * @param string $file * @param string $backup * * @return bool * * @throws LSCMException Thrown indirectly by Logger::debug() call. * @throws LSCMException Thrown indirectly by Logger::debug() call. */ private static function matchFileSettings( $file, $backup ) { clearstatcache(); $ownerID = fileowner($file); $groupID = filegroup($file); if ( $ownerID === false || $groupID === false ) { Logger::debug("Could not get owner/group of file $file"); unlink($backup); Logger::debug("Removed file $backup"); return false; } self::changeUserGroup($backup, $ownerID, $groupID); self::matchPermissions($file, $backup); return true; } /** * * @param string $filepath * @param string $bak * * @return string */ private static function getBackupSuffix( $filepath, $bak = '_lscachebak_orig' ) { $i = 1; if ( file_exists($filepath . $bak) ) { $bak = sprintf("_lscachebak_%02d", $i); while ( file_exists($filepath . $bak) ) { $i++; $bak = sprintf("_lscachebak_%02d", $i); } } return $bak; } /** * * @param string $filepath * * @return bool * * @throws LSCMException Thrown indirectly by Logger::debug() call. * @throws LSCMException Thrown indirectly by Logger::verbose() call. * @throws LSCMException Thrown indirectly by self::matchFileSettings() * call. * @throws LSCMException Thrown indirectly by Logger::debug() call. * @throws LSCMException Thrown indirectly by Logger::debug() call. * @throws LSCMException Thrown indirectly by Logger::info() call. */ public static function createBackup( $filepath ) { $backup = $filepath . self::getBackupSuffix($filepath); if ( !copy($filepath, $backup) ) { Logger::debug( "Could not backup file $filepath to location $backup" ); return false; } Logger::verbose("Created file $backup"); if ( !self::matchFileSettings($filepath, $backup) ) { Logger::debug( "Could not backup file $filepath to location $backup" ); return false; } Logger::debug('Matched owner/group setting for both files'); Logger::info( "Successfully backed up file $filepath to location $backup" ); return true; } /** * * @param string $zipFile * @param string $dest * * @return bool * * @throws LSCMException Thrown indirectly by Logger::debug() call. * @throws LSCMException Thrown indirectly by Logger::debug() call. */ public static function unzipFile( $zipFile, $dest ) { if ( class_exists('\ZipArchive') ) { $zipArchive = new ZipArchive(); if ( $zipArchive->open($zipFile) === true ) { $extracted = $zipArchive->extractTo($dest); $zipArchive->close(); if ( $extracted ) { return true; } } Logger::debug("Could not unzip $zipFile using ZipArchive."); } $output = array(); exec( "unzip $zipFile -d $dest > /dev/null 2>&1", $output, $return_var ); if ( $return_var == 0 ) { return true; } else { Logger::debug("Could not unzip $zipFile from cli."); } return false; } /** * Check if a given directory is empty. * * @param string $dir * * @return bool */ public static function is_dir_empty( $dir ) { if ( !($handle = @opendir($dir)) ) { return true; } while ( ($entry = readdir($handle)) !== false ) { if ( $entry != '.' && $entry != '..' ) { return false; } } return true; } /** * * @param string $vhCacheRoot */ public static function ensureVHCacheRootInCage( $vhCacheRoot ) { $cageFsFile = '/etc/cagefs/cagefs.mp'; if ( file_exists($cageFsFile) ) { if ( $vhCacheRoot[0] == '/' ) { $cageVhCacheRoot = '%' . str_replace('/$vh_user', '', $vhCacheRoot); $matchFound = preg_grep( "!^\s*" . str_replace('!', '\!', $cageVhCacheRoot) . "!im", file($cageFsFile) ); if ( !$matchFound ) { file_put_contents( $cageFsFile, "\n$cageVhCacheRoot", FILE_APPEND ); exec('/usr/sbin/cagefsctl --remount-all'); } } } } /** * Recursively a directory's contents and optionally the directory itself. * * @param string $dir Directory path * @param bool $keepParent Only remove directory contents when true. * * @return bool */ public static function rrmdir( $dir, $keepParent = false ) { if ( $dir != '' && is_dir($dir) ) { if ( ($matches = glob("$dir/*")) === false ) { return false; } foreach ( $matches as $file ) { if ( is_dir($file) ) { self::rrmdir($file); } else { unlink($file); } } if ( !$keepParent ) { rmdir($dir); } return true; } return false; } /** * Wrapper for idn_to_utf8() function call to avoid "undefined" exceptions * when PHP intl module is not installed and enabled. * * @since 1.13.13.1 * * @param string $domain * @param int $flags * @param int|null $variant * @param array|null $idna_info * * @return false|string */ public static function tryIdnToUtf8( $domain, $flags = 0, $variant = null, array &$idna_info = null ) { if ( function_exists('idn_to_utf8') ) { if ( $variant == null ) { $variant = INTL_IDNA_VARIANT_UTS46; } return idn_to_utf8($domain, $flags, $variant, $idna_info); } return $domain; } /** * Wrapper for idn_to_ascii() function call to avoid "undefined" exceptions * when PHP intl module is not installed and enabled. * * @since 1.13.13.1 * * @param string $domain * @param int|null $flags * @param int|null $variant * @param array|null $idna_info * * @return false|string */ public static function tryIdnToAscii( $domain, $flags = null, $variant = null, array &$idna_info = null ) { if ( function_exists('idn_to_ascii') ) { if ( $flags == null ) { $flags = IDNA_DEFAULT; } if ( $variant == null ) { $variant = INTL_IDNA_VARIANT_UTS46; } return idn_to_ascii($domain, $flags, $variant, $idna_info); } return $domain; } /** * Version comparison function capable of properly comparing versions with * trailing ".0" groups such as '6.1' which is equal to '6.1.0' which is * equal to '6.1.000.0' etc. * * @since 1.14.2 * * @param string $ver1 * @param string $ver2 * @param string|null $operator * * @return bool|int */ public static function betterVersionCompare( $ver1, $ver2, $operator = null ) { $pattern = '/(\.0+)+($|-)/'; return version_compare( preg_replace($pattern, '', $ver1), preg_replace($pattern, '', $ver2), $operator ); } /** * * @since 1.15.0.1 * * @param string $constantName * @param array|bool|float|int|null|string $value * @param bool $caseInsensitive Optional * parameter used for define calls in PHP versions below 7.3. * * @return bool * * @noinspection PhpDeprecationInspection Ignore deprecation of define() * parameter $case_insensitive for PHP versions below 7.3. * @noinspection RedundantSuppression */ public static function define_wrapper( $constantName, $value, $caseInsensitive = false ) { if ( PHP_VERSION_ID < 70300 ) { return define($constantName, $value, $caseInsensitive); } else { return define($constantName, $value); } } /** * * @since 1.17.1.1 * * @param int $wpStatus * * @return string[] [ stateMsg => string, link => string ] */ public static function getFatalErrorStateMessageAndLink( $wpStatus ) { $stateMsg = $anchor = ''; if ( $wpStatus & WPInstall::ST_ERR_EXECMD ) { $stateMsg = 'WordPress fatal error encountered during action ' . 'execution. This is most likely caused by custom code in ' . 'this WordPress installation.'; $anchor = '#fatal-error-encountered-during-action-execution'; } if ( $wpStatus & WPInstall::ST_ERR_EXECMD_DB ) { $stateMsg = 'Error establishing WordPress database connection.'; } elseif ( $wpStatus & WPInstall::ST_ERR_TIMEOUT ) { $stateMsg = 'Timeout occurred during action execution.'; $anchor = '#timeout-occurred-during-action-execution'; } elseif ( $wpStatus & WPInstall::ST_ERR_SITEURL ) { $stateMsg = 'Could not retrieve WordPress siteURL.'; $anchor = '#could-not-retrieve-wordpress-siteurl'; } elseif ( $wpStatus & WPInstall::ST_ERR_DOCROOT ) { $stateMsg = 'Could not match WordPress siteURL to a known ' . 'control panel docroot.'; $anchor = '#could-not-match-wordpress-siteurl-to-a-known-' . 'cpanel-docroot'; } elseif ( $wpStatus & WPInstall::ST_ERR_WPCONFIG ) { $stateMsg = 'Could not find a valid wp-config.php file.'; $anchor = '#could-not-find-a-valid-wp-configphp-file'; } $stateMsg .= ' Click for more information.'; return array( 'stateMsg' => $stateMsg, 'link' => 'https://docs.litespeedtech.com/lsws/cp/cpanel/' . "whm-litespeed-plugin/troubleshooting/$anchor" ); } }