?
Current Path : /home1/savoy/public_html/wp-content/plugins/duplicator/src/Libs/Snap/ |
Linux gator3171.hostgator.com 4.19.286-203.ELK.el7.x86_64 #1 SMP Wed Jun 14 04:33:55 CDT 2023 x86_64 |
Current File : /home1/savoy/public_html/wp-content/plugins/duplicator/src/Libs/Snap/SnapWP.php |
<?php /** * * @package Duplicator * @copyright (c) 2022, Snap Creek LLC */ namespace Duplicator\Libs\Snap; use Exception; use WP_Roles; use WP_Site; use WP_Theme; use wpdb; /** * Wordpress utility functions * * old: SnapWP */ class SnapWP { const DEFAULT_MAX_GET_SITES_NUMBER = 10000; const PATH_FULL = 0; const PATH_RELATIVE = 1; const PATH_AUTO = 2; const PLUGIN_INFO_ALL = 0; const PLUGIN_INFO_ACTIVE = 1; const PLUGIN_INFO_INACTIVE = 2; /** * * @var string if not empty alters isWpCore's operation */ private static $wpCoreRelativePath = ''; /** @var ?array<string, mixed> initialized inside wordpress_core_files.php */ private static $corePathList = null; /** * return safe ABSPATH without last / * perform safe function only one time * * @return string */ public static function getSafeAbsPath() { static $safeAbsPath = null; if (is_null($safeAbsPath)) { if (defined('ABSPATH')) { $safeAbsPath = SnapIO::safePathUntrailingslashit(ABSPATH); } else { $safeAbsPath = ''; } } return $safeAbsPath; } /** * Return wp-config path or false if not found * * @return bool|string */ public static function getWPConfigPath() { static $configPath = null; if (is_null($configPath)) { $absPath = SnapIO::safePathTrailingslashit(ABSPATH, true); $absParent = dirname($absPath) . '/'; if (file_exists($absPath . 'wp-config.php')) { $configPath = $absPath . 'wp-config.php'; } elseif (@file_exists($absParent . 'wp-config.php') && !@file_exists($absParent . 'wp-settings.php')) { $configPath = $absParent . 'wp-config.php'; } else { $configPath = false; } } return $configPath; } /** * Get wordpress table info by table name * * @param string $table table name * @param string $prefix wordpress prefix * * @return array{isCore: bool, havePrefix: bool, subsiteId: int, isMultisiteCore: bool} */ public static function getTableInfoByName($table, $prefix) { $result = array( 'isCore' => false, 'havePrefix' => false, 'subsiteId' => -1, 'isMultisiteCore' => false ); if (preg_match('/^' . preg_quote($prefix, '/') . '(?:(\d+)_)?(.+)/', $table, $matches) !== 1) { return $result; } $result['havePrefix'] = true; $nameWithoutPrefix = $matches[2]; $result['isMultisiteCore'] = in_array($nameWithoutPrefix, self::getMultisiteTables()); $result['isCore'] = $result['isMultisiteCore'] || in_array($nameWithoutPrefix, self::getSiteCoreTables()); if (is_numeric($matches[1])) { $result['subsiteId'] = (int) $matches[1]; } elseif (!$result['isMultisiteCore']) { $result['subsiteId'] = 1; } return $result; } /** * Get the list of wp prefixes from given tables list * * @param string[] $tables List of table names to check for unique WP prefixes * * @return string[] */ public static function getUniqueWPTablePrefixes($tables) { $userPrefix = array(); $userMetaPrefix = array(); foreach ($tables as $table) { if (preg_match("/^(.*)users$/m", $table, $matches)) { $userPrefix[] = $matches[1]; } elseif (preg_match("/^(.*)usermeta$/m", $table, $matches)) { $userMetaPrefix[] = $matches[1]; } } return array_intersect($userPrefix, $userMetaPrefix); } /** * Modifies the database based on specified SQL statements. * * Useful for creating new tables and updating existing tables to a new structure. * * From Wordpress dbDelta * * @global \wpdb $wpdb WordPress database abstraction object. * * @param string[]|string $queries Optional. The query to run. Can be multiple queries * in an array, or a string of queries separated by * semicolons. Default empty string. * @param bool $execute Optional. Whether or not to execute the query right away. * Default true. * * @return string[] Strings containing the results of the various update queries. */ public static function dbDelta($queries = '', $execute = true) { $mysqliDriver = new \mysqli_driver(); $defReporting = $mysqliDriver->report_mode; mysqli_report(MYSQLI_REPORT_OFF); $result = dbDelta($queries, $execute); mysqli_report($defReporting); return $result; } /** * Schedules cron event if it's not already scheduled. * * @param int $timestamp Timestamp of the first next run time * @param string $cronIntervalName Name of cron interval to be used * @param string $hook Hook that we want to assign to the given cron interval * * @return void */ public static function scheduleEvent($timestamp, $cronIntervalName, $hook) { if (!wp_next_scheduled($hook)) { // Assign the hook to the schedule wp_schedule_event($timestamp, $cronIntervalName, $hook); } } /** * Unschedules cron event if it's scheduled. * * @param string $hook Name of the hook that we want to unschedule * * @return void */ public static function unscheduleEvent($hook) { if (wp_next_scheduled($hook)) { // Unschedule the hook $timestamp = wp_next_scheduled($hook); wp_unschedule_event($timestamp, $hook); } } /** * Get Auto_increment value of wp_blogs table in multisite. * That is id of the first next subsite that will be imported. * * @return int // returns Auto_increment value of wp_blogs table in multisite, * // returns -1 if Auto_increment value can not be obtained for any reason */ public static function getNextSubsiteIdAI() { $nextSubsiteIdAI = -1; if (!is_multisite()) { return $nextSubsiteIdAI; } /** @var \wpdb $wpdb */ global $wpdb; $sql = $wpdb->prepare("SHOW TABLE STATUS LIKE %s", $wpdb->prefix . "blogs"); $result = $wpdb->get_results($sql, ARRAY_A); if (count($result) < 1) { return $nextSubsiteIdAI; } $row = $result[0]; if (array_key_exists("Auto_increment", $row)) { $nextSubsiteIdAI = intval($row["Auto_increment"]); } return $nextSubsiteIdAI; } /** * From a tables list filters all tables without WP prefix * * @param string[] $tables tables list * * @return string[] */ public static function getTablesWithPrefix($tables) { /** @var \wpdb $wpdb */ global $wpdb; $tables = (array) $tables; $result = array(); foreach ($tables as $table) { if (strpos($table, $wpdb->prefix) === 0) { $result[] = $table; } } return $result; } /** * Check if passed folder is home folder * * @param string $folder folder path * * @return boolean return true if folder is wordpress home folder */ public static function isWpHomeFolder($folder) { $indexPhp = SnapIO::trailingslashit($folder) . 'index.php'; if (!file_exists($indexPhp)) { return false; } if (($indexContent = file_get_contents($indexPhp)) === false) { return false; } return (preg_match('/^.*\srequire.*?[\'"].*wp-blog-header\.php[\'"].*?;.*$/s', $indexContent) === 1); } /** * This function is the equivalent of the get_home_path function but with various fixes * * @return string */ public static function getHomePath() { static $home_path = null; if (is_null($home_path)) { // outside wordpress this function makes no sense if (!defined('ABSPATH')) { $home_path = ''; return $home_path; } if (isset($_SERVER['SCRIPT_FILENAME']) && is_readable($_SERVER['SCRIPT_FILENAME'])) { $scriptFilename = $_SERVER['SCRIPT_FILENAME']; } else { $files = get_included_files(); $scriptFilename = array_shift($files); } $realScriptDirname = SnapIO::safePathTrailingslashit(dirname($scriptFilename), true); $realAbsPath = SnapIO::safePathTrailingslashit(ABSPATH, true); if (strpos($realScriptDirname, $realAbsPath) === 0) { // normalize URLs without www $home = SnapURL::wwwRemove(set_url_scheme(get_option('home'), 'http')); $siteurl = SnapURL::wwwRemove(set_url_scheme(get_option('siteurl'), 'http')); if (!empty($home) && 0 !== strcasecmp($home, $siteurl)) { if (stripos($siteurl, $home) === 0) { $wp_path_rel_to_home = str_ireplace($home, '', $siteurl); /* $siteurl - $home */ $pos = strripos( str_replace('\\', '/', $scriptFilename), SnapIO::trailingslashit($wp_path_rel_to_home) ); $home_path = substr($scriptFilename, 0, $pos); $home_path = SnapIO::trailingslashit($home_path); } else { $home_path = ABSPATH; } } else { $home_path = ABSPATH; } } else { // On frontend the home path is the folder of index.php $home_path = SnapIO::trailingslashit(dirname($scriptFilename)); } // make sure the folder exists or consider ABSPATH if (!file_exists($home_path)) { $home_path = ABSPATH; } $home_path = str_replace('\\', '/', $home_path); } return $home_path; } /** * Return admin url, if is multisite return network_admin_url * * @param string $path Optional. Path relative to the admin URL. Default 'admin'. * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). * 'http' or 'https' can be passed to force those schemes. * * @return string Admin URL link with optional path appended. */ public static function getAdminUrl($path, $scheme = 'admin') { if (is_multisite()) { return network_admin_url($path, $scheme); } else { return admin_url($path, $scheme); } } /** * Ser relative abs path * * @param string $string abs path * * @return void */ public static function setWpCoreRelativeAbsPath($string = '') { self::$wpCoreRelativePath = (string) $string; } /** * check if path is in wordpress core list * PATH_FULL and PATH_RELATIVE is better optimized and perform less operations * * @param string $path file path * @param int $fullPath if PATH_AUTO check if is a full path or relative path * if PATH_FULL remove ABSPATH len without check * if PATH_RELATIVE consider path a relative path * @param bool $isSafe if false call rtrim(SnapIO::safePath( PATH ), '/') * if true consider path a safe path without check * * @return boolean */ public static function isWpCore($path, $fullPath = self::PATH_AUTO, $isSafe = false) { if ($isSafe == false) { $path = rtrim(SnapIO::safePath($path), '/'); } switch ($fullPath) { case self::PATH_FULL: $absPath = self::getSafeAbsPath(); if (strlen($path) < strlen($absPath)) { return false; } $relPath = ltrim(substr($path, strlen($absPath)), '/'); break; case self::PATH_RELATIVE: if (($relPath = SnapIO::getRelativePath($path, self::$wpCoreRelativePath)) === false) { return false; } break; case self::PATH_AUTO: default: $absPath = self::getSafeAbsPath(); if (strpos($path, $absPath) === 0) { $relPath = ltrim(substr($path, strlen($absPath)), '/'); } else { $relPath = ltrim($path, '/'); } } // if rel path is empty is consider root path so is a core folder. if (strlen($relPath) === 0) { return true; } $pExploded = explode('/', $relPath); $corePaths = self::getCorePathsList(); foreach ($pExploded as $current) { if (!isset($corePaths[$current])) { return false; } if (is_scalar($corePaths[$current])) { // is file so don't have childs $corePaths = array(); } else { $corePaths = $corePaths[$current]; } } return true; } /** * * @param string $relPath If empty is consider abs root path * * @return array{dirs: string[], files: string[]} */ public static function getWpCoreFilesListInFolder($relPath = '') { $corePaths = self::getCorePathsList(); if (strlen($relPath) > 0) { $pExploded = explode('/', $relPath); foreach ($pExploded as $current) { if (!isset($corePaths[$current])) { $corePaths = array(); break; } if (is_scalar($corePaths[$current])) { // is file so don't have childs $corePaths = array(); } else { $corePaths = $corePaths[$current]; } } } $result = array( 'dirs' => array(), 'files' => array() ); foreach ($corePaths as $name => $content) { if (is_array($content)) { $result['dirs'][] = $name; } else { $result['files'][] = $name; } } return $result; } /** * Get core path list from relative abs path * [ * 'folder' => [ * 's-folder1' => [ * file1 => [], * file2 => [], * ], * 's-folder2' => [], * file1 => [] * ] * ] * * @return array<string, mixed[]> */ public static function getCorePathsList() { if (is_null(self::$corePathList)) { require_once(dirname(__FILE__) . '/wordpress_core_files.php'); } return self::$corePathList; } /** * Get List of core folders inside the wp-content folder * * @return string[] */ public static function getWPContentCoreDirs() { return array( 'languages', 'cache' ); } /** * Returns the main site ID for the network. * * Copied from the source of the get_main_site_id() except first line in https://developer.wordpress.org/reference/functions/get_main_site_id/ * get_main_site_id() is introduced in WP 4.9.0. It is for backward compatibility * * @param int|null $network_id network id * * @return int The ID of the main site. */ public static function getMainSiteId($network_id = null) { // For > WP 4.9.0 if (function_exists('get_main_site_id')) { return get_main_site_id($network_id); } if (!is_multisite()) { return get_current_blog_id(); } $network = function_exists('get_network') ? get_network($network_id) : wp_get_network($network_id); if (!$network) { return 0; } return $network->site_id; } /** * Return object list of sites * * @param string|array<string, mixed> $args list of filters, see wordpress get_sites function * * @return false|WP_Site[]|int[] site list or ids or false if isn't multisite */ public static function getSites($args = array()) { if (!function_exists('is_multisite') || !is_multisite()) { return false; } if (!isset($args['number'])) { $args['number'] = self::DEFAULT_MAX_GET_SITES_NUMBER; } if (function_exists('get_sites')) { return get_sites($args); } else { $result = array(); $blogs = wp_get_sites($args); $returnIds = (isset($args['fields']) && $args['fields'] === 'ids'); foreach ($blogs as $blog) { if (is_array($blog)) { $blog = (object) $blog; } $result[] = ($returnIds ? $blog->blog_id : $blog); } return $result; } } /** * Return list of subiste ids * * @return int[] */ public static function getSitesIds() { if (!is_multisite()) { return array(1); } return SnapWP::getSites(array('fields' => 'ids')); } /** * return the list of possible dropins plugins * * @return string[] */ public static function getDropinsPluginsNames() { return array( 'advanced-cache.php', // WP_CACHE 'db.php', // auto on load 'db-error.php', // auto on error 'install.php', // auto on installation 'maintenance.php', // auto on maintenance 'object-cache.php', // auto on load 'php-error.php', // auto on error 'fatal-error-handler.php', // auto on error 'sunrise.php', 'blog-deleted.php', 'blog-inactive.php', 'blog-suspended.php' ); } /** * Return site and subsite tables names without prefix * * @return string[] */ public static function getSiteCoreTables() { return array( 'commentmeta', 'comments', 'links', 'options', 'postmeta', 'posts', 'term_relationships', 'term_taxonomy', 'terms', 'termmeta' ); } /** * Return multisite general tables without prefix * * @return string[] */ public static function getMultisiteTables() { return array( 'blogmeta', 'blogs', 'blog_versions', 'registration_log', 'signups', 'site', 'sitemeta' ); } /** * Returns gmt_offset * 3600 * * @return int timezone offset in seconds */ public static function getGMTOffset() { return get_option('gmt_offset') ? ((float) get_option('gmt_offset')) * 3600 : 0; } /** * Returns wp option "timezone_string" * * @return string // timezone_string, will be empty if manual offset is chosen */ public static function getTimeZoneString() { static $timezoneString = null; if (is_null($timezoneString)) { $timezoneString = get_option('timezone_string'); } return $timezoneString; } /** * Returns 1 if DST is active on given timestamp, 0 if it's not active. * Currently active timezone is taken into account. * * @param int $timestamp In seconds * * @return int 1 if DST is active, 0 otherwise */ public static function getDST($timestamp) { $timezoneString = self::getTimeZoneString(); if (!$timezoneString) { // There is no DST if manual offset is chosen in WP settings timezone return 0; } $date = new \DateTime(); $date->setTimestamp($timestamp); $date->setTimezone(new \DateTimeZone($timezoneString)); return (int) $date->format('I'); } /** * Converts timestamp to date string with given format, according to * currently selected timezone in Wordpress settings * * @param string $format Format for date * @param int $timestamp In seconds * * @return string Date converted to string in currently selected timezone */ public static function getDateInWPTimezone($format, $timestamp) { $timezoneString = self::getTimeZoneString(); if ($timezoneString) { // Particular timezone is selected, not manual offset. This means that DST could be in place, // and we can't use current gmt_offset. We have to use the timezone! $date = new \DateTime(); $date->setTimestamp($timestamp); $date->setTimezone(new \DateTimeZone($timezoneString)); return $date->format($format); } // Manual offset is selected. In this case there is no DST so we can // create the date string using current gmt_offset. $local_time = $timestamp + SnapWP::getGMTOffset(); return (string) date($format, $local_time); } /** * * @param int $blogId if multisite and blogId > 0 return the user of blog * * @return array<object{ID: int, user_login: string}> */ public static function getAdminUserLists($blogId = 0) { $args = array( 'fields' => array('ID', 'user_login') ); if (is_multisite()) { $args['blog_id'] = $blogId; if ($blogId == 0) { $args['login__in'] = get_site_option('site_admins'); } } else { $args['role'] = 'administrator'; } return get_users($args); } /** * Get users count * * @return int */ public static function getUsersCount() { global $wpdb; $sql = "SELECT COUNT(ID) FROM $wpdb->users"; return (int) $wpdb->get_var($sql); } /** * Return post types count * * @return array<string, int> */ public static function getPostTypesCount() { $postTypes = get_post_types(); $postTypeCount = array(); foreach ($postTypes as $postName) { $postObj = get_post_type_object($postName); if (!$postObj->public) { continue; } /** @var int[] */ $postCountForTypes = (array) wp_count_posts($postName); $postCount = 0; foreach ($postCountForTypes as $num) { $postCount += $num; } $postTypeCount[$postObj->label] = $postCount; } return $postTypeCount; } /** * Get plugins array info with multisite, must-use and drop-ins * * @param string $key User meta key * * @return bool true on success, false on failure */ public static function deleteUserMetaKey($key) { /** @var wpdb $wpdb */ global $wpdb; if ( $wpdb->delete( $wpdb->usermeta, array('meta_key' => $key), array('%s') ) === false ) { return false; } return true; } /** * return plugin formatted data from plugin info * * @param WP_Theme $theme instance of WP Core class WP_Theme. theme info from get_themes function * * @return array<string, mixed> */ protected static function getThemeArrayData(WP_Theme $theme) { $slug = $theme->get_stylesheet(); $parent = $theme->parent(); return array( 'slug' => $slug, 'themeName' => $theme->get('Name'), 'version' => $theme->get('Version'), 'themeURI' => $theme->get('ThemeURI'), 'parentTheme' => (false === $parent) ? false : $parent->get_stylesheet(), 'template' => $theme->get_template(), 'stylesheet' => $theme->get_stylesheet(), 'description' => $theme->get('Description'), 'author' => $theme->get('Author'), "authorURI" => $theme->get('AuthorURI'), 'tags' => $theme->get('Tags'), 'isAllowed' => $theme->is_allowed(), 'isActive' => (is_multisite() ? array() : false), 'defaultTheme' => (defined('WP_DEFAULT_THEME') && WP_DEFAULT_THEME == $slug), ); } /** * get themes array info with active template, stylesheet * * @return array<string, mixed[]> */ public static function getThemesInfo() { if (!function_exists('wp_get_themes')) { require_once ABSPATH . 'wp-admin/includes/theme.php'; } $result = array(); foreach (wp_get_themes() as $slug => $theme) { $result[$slug] = self::getThemeArrayData($theme); } if (is_multisite()) { foreach (SnapWP::getSitesIds() as $siteId) { switch_to_blog($siteId); $stylesheet = get_stylesheet(); if (isset($result[$stylesheet])) { $result[$stylesheet]['isActive'][] = $siteId; } //Also set parent theme to active if it exists $template = get_template(); if ($template !== $stylesheet && isset($result[$template])) { $result[$template]['isActive'][] = $siteId; } restore_current_blog(); } } else { $stylesheet = get_stylesheet(); if (isset($result[$stylesheet])) { $result[$stylesheet]['isActive'] = true; } //Also set parent theme to active if it exists $template = get_template(); if ($template !== $stylesheet && isset($result[$template])) { $result[$template]['isActive'] = true; } } return $result; } /** * Get plugins array info with multisite, must-use and drop-ins * * @param int $filter ENUM: PLUGIN_INFO_ALL, PLUGIN_INFO_ACTIVE, PLUGIN_INFO_INACTIVE * * @return array<string, mixed[]> */ public static function getPluginsInfo($filter = self::PLUGIN_INFO_ALL) { if (!defined('ABSPATH')) { throw new Exception('This function can be used only on wp'); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } // parse all plugins $result = array(); foreach (get_plugins() as $path => $plugin) { $result[$path] = self::getPluginArrayData($path, $plugin); $result[$path]['networkActive'] = is_plugin_active_for_network($path); if (!is_multisite()) { $result[$path]['active'] = is_plugin_active($path); } else { // if is _multisite the active value is an array with the blog ids list where the plugin is active $result[$path]['active'] = array(); } } // If is _multisite the active value is an array with the blog ids list where the plugin is active if (is_multisite()) { foreach (SnapWP::getSitesIds() as $siteId) { switch_to_blog($siteId); foreach ($result as $path => $plugin) { if (!$result[$path]['networkActive'] && is_plugin_active($path)) { $result[$path]['active'][] = $siteId; } } restore_current_blog(); } } // parse all must use plugins foreach (get_mu_plugins() as $path => $plugin) { $result[$path] = self::getPluginArrayData($path, $plugin); $result[$path]['mustUse'] = true; } // parse all dropins plugins foreach (get_dropins() as $path => $plugin) { $result[$path] = self::getPluginArrayData($path, $plugin); $result[$path]['dropIns'] = true; } switch ($filter) { case self::PLUGIN_INFO_ACTIVE: return array_filter( $result, function ($info) { return SnapWP::isPluginActiveByInfo($info); } ); case self::PLUGIN_INFO_INACTIVE: return array_filter( $result, function ($info) { return !SnapWP::isPluginActiveByInfo($info); } ); case self::PLUGIN_INFO_ALL: default: return $result; } } /** * Determine if a plugin is active by info * * @param array{active: bool|bool[], networkActive: bool, dropIns: bool, mustUse: bool} $info Plugin info * * @return bool */ protected static function isPluginActiveByInfo($info) { return ( $info['active'] === true || $info['networkActive'] || ( is_array($info['active']) && !empty($info['active']) ) || $info['dropIns'] || $info['mustUse'] ); } /** * Check if a plugin is installed * * @param string $pluginSlug plugin slug * * @return bool */ public static function isPluginInstalled($pluginSlug) { if (!defined('ABSPATH')) { throw new Exception('This function can be used only on wp'); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $plugins = array_keys(get_plugins()); return in_array($pluginSlug, $plugins); } /** * return plugin formatted data from plugin info * plugin info = Array ( * [Name] => Hello Dolly * [PluginURI] => http://wordpress.org/extend/plugins/hello-dolly/ * [Version] => 1.6 * [Description] => This is not just ... * [Author] => Matt Mullenweg * [AuthorURI] => http://ma.tt/ * [TextDomain] => * [DomainPath] => * [Network] => * [Title] => Hello Dolly * [AuthorName] => Matt Mullenweg * ) * * @param string $slug plugin slug * @param array<string, mixed> $plugin pluhin info from get_plugins function * * @return array<string, mixed> */ protected static function getPluginArrayData($slug, $plugin) { return array( 'slug' => $slug, 'name' => $plugin['Name'], 'version' => $plugin['Version'], 'pluginURI' => $plugin['PluginURI'], 'author' => $plugin['Author'], 'authorURI' => $plugin['AuthorURI'], 'description' => $plugin['Description'], 'title' => $plugin['Title'], 'networkActive' => false, 'active' => false, 'mustUse' => false, 'dropIns' => false ); } /** * Retrieves the global WP_Roles instance and instantiates it if necessary. * Added for compatibility with WP < 4.3 * * @return WP_Roles WP_Roles global instance if not already instantiated. */ public static function wpRoles() { if (function_exists('wp_roles')) { return wp_roles(); } global $wp_roles; if (! isset($wp_roles)) { $wp_roles = new WP_Roles(); } return $wp_roles; } }