.htaccess
9 months ago
Blog.php
9 months ago
Helper.php
9 months ago
Init.php
9 months ago
Installer.php
9 months ago
MySQL.php
9 months ago
UI.php
9 months ago
Update.php
9 months ago
Wordpress.php
9 months ago
index.html
9 months ago
web.config
9 months ago
Helper.php
269 lines
| 1 | <?php |
| 2 | |
| 3 | namespace JetBackup\Wordpress; |
| 4 | |
| 5 | use Exception; |
| 6 | use JetBackup\Alert\Alert; |
| 7 | use JetBackup\Entities\Util; |
| 8 | use JetBackup\Exception\IOException; |
| 9 | use JetBackup\Factory; |
| 10 | use JetBackup\JetBackup; |
| 11 | use WP_User; |
| 12 | |
| 13 | if (!defined( '__JETBACKUP__')) die('Direct access is not allowed'); |
| 14 | |
| 15 | class Helper { |
| 16 | |
| 17 | private string $_homedir=''; |
| 18 | |
| 19 | private const SUPPORT_USER_TTL = 30 * 24 * 60 * 60; // 30 days in seconds |
| 20 | |
| 21 | public static function isMainSite(): bool { |
| 22 | return (function_exists('is_main_site') && is_main_site()); |
| 23 | } |
| 24 | |
| 25 | public static function getMainSiteId(): int { |
| 26 | $main_site_id = 1; |
| 27 | if (function_exists('get_main_site_id')) return get_main_site_id(); |
| 28 | if (function_exists('get_site_option')) $main_site_id = (int) get_site_option('main_site_id'); |
| 29 | if ($main_site_id > 0) return $main_site_id; |
| 30 | return $main_site_id; |
| 31 | } |
| 32 | |
| 33 | public static function isMultisite(): bool { |
| 34 | if (function_exists('is_multisite') && is_multisite()) return true; |
| 35 | if (defined( 'MULTISITE')) return MULTISITE; |
| 36 | if (defined( 'SUBDOMAIN_INSTALL') || defined( 'VHOST') || defined( 'SUNRISE')) return true; |
| 37 | return false; |
| 38 | } |
| 39 | |
| 40 | public static function isNetworkAdminUser(): bool { |
| 41 | return function_exists('current_user_can') && current_user_can('manage_network') && |
| 42 | function_exists('is_super_admin') && is_super_admin(); |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * @throws Exception |
| 47 | */ |
| 48 | public static function getWordpressUser($username) : ?array { |
| 49 | |
| 50 | if(!function_exists('get_user_by')) throw new Exception("Function get_user_by() not defined"); |
| 51 | if(!function_exists('wp_set_password')) throw new Exception("Function wp_set_password() not defined"); |
| 52 | |
| 53 | $user = get_user_by('login', $username); |
| 54 | if(!$user) return null; |
| 55 | |
| 56 | |
| 57 | $password = Util::generatePassword(); |
| 58 | wp_set_password($password, $user->ID); |
| 59 | |
| 60 | return [ |
| 61 | 'username' => $user->user_login, |
| 62 | 'email' => $user->user_email, |
| 63 | 'password' => $password, |
| 64 | 'wordpress_admin_url' => Wordpress::getAdminURL(), |
| 65 | |
| 66 | ]; |
| 67 | |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * @throws Exception |
| 72 | */ |
| 73 | public static function clearSupportUser() : void { |
| 74 | |
| 75 | $config = Factory::getConfig(); |
| 76 | if(!$username = $config->getSupportUsername()) return; |
| 77 | if(!$user = get_user_by('login', $username)) return; |
| 78 | $user_created_date = $user->data->user_registered ?? null; |
| 79 | if(!$user_created_date) return; |
| 80 | if(!$user_created_timestamp = strtotime($user_created_date)) return; |
| 81 | |
| 82 | if ((time() - $user_created_timestamp) > self::SUPPORT_USER_TTL) { |
| 83 | |
| 84 | if (self::isMultisite()) { |
| 85 | if (!function_exists('wpmu_delete_user')) require_once WP_ROOT . JetBackup::SEP . 'wp-admin' . JetBackup::SEP . 'includes' . JetBackup::SEP . 'ms.php'; |
| 86 | revoke_super_admin($user->ID); // super admin user is protected by wp_delete user, so we need to revoke first |
| 87 | wpmu_delete_user($user->ID); |
| 88 | } else { |
| 89 | if (!function_exists('wp_delete_user')) require_once WP_ROOT . JetBackup::SEP . 'wp-admin' . JetBackup::SEP . 'includes' . JetBackup::SEP . 'user.php'; |
| 90 | wp_delete_user($user->ID); |
| 91 | } |
| 92 | $config->setSupportUsername(''); |
| 93 | $config->save(); |
| 94 | Alert::add('System Cleanup', "Temporary support user '{$user->data->user_login}' created 30 days ago removed", Alert::LEVEL_INFORMATION); |
| 95 | } |
| 96 | |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * @throws IOException |
| 101 | * @throws Exception |
| 102 | */ |
| 103 | public static function createSupportUser() : array { |
| 104 | |
| 105 | $config = Factory::getConfig(); |
| 106 | $username = $config->getSupportUsername(); |
| 107 | if ($username && $output = self::getWordpressUser($username)) return $output; |
| 108 | |
| 109 | if(!function_exists('wp_create_user')) throw new Exception("Function wp_create_user() not defined"); |
| 110 | if(!function_exists('grant_super_admin')) throw new Exception("Function grant_super_admin() not defined"); |
| 111 | |
| 112 | // Generate new user details |
| 113 | $email = "support+" . Util::generateRandomString(5) . "@jetbackup.com"; |
| 114 | $password = Util::generatePassword(); |
| 115 | $username = "jetbackup_" . Util::generateRandomString(5); |
| 116 | |
| 117 | // Create new user |
| 118 | $user_id = wp_create_user($username, $password, $email); |
| 119 | if (is_wp_error($user_id)) throw new Exception($user_id->get_error_message()); |
| 120 | |
| 121 | $user = new WP_User($user_id); |
| 122 | $user->set_role('administrator'); |
| 123 | if (self::isMultisite()) grant_super_admin($user_id); // Grant network admin privileges |
| 124 | |
| 125 | $config->setSupportUsername($username); |
| 126 | $config->save(); |
| 127 | |
| 128 | return [ |
| 129 | 'username' => $user->user_login, |
| 130 | 'email' => $email, |
| 131 | 'password' => $password, |
| 132 | 'wordpress_admin_url' => Wordpress::getAdminURL(), |
| 133 | ]; |
| 134 | |
| 135 | } |
| 136 | |
| 137 | public static function isAdminUser(): bool { |
| 138 | return function_exists('current_user_can') && current_user_can('manage_options') && |
| 139 | function_exists('is_super_admin') && is_super_admin(); |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Returns true/false if I am in the network admin GUI interface (not if I am network admin USER) |
| 144 | * @return bool |
| 145 | */ |
| 146 | public static function isNetworkAdminInterface(): bool { |
| 147 | if (function_exists('is_network_admin') && is_network_admin()) return true; |
| 148 | if (isset($GLOBALS['current_screen'])) return $GLOBALS['current_screen']->in_admin( 'network' ); |
| 149 | elseif (defined('WP_NETWORK_ADMIN')) return WP_NETWORK_ADMIN; |
| 150 | return false; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * @param bool $public |
| 155 | * Example output: /home/user/public_html/ |
| 156 | * public flag: public_html (no ending /) |
| 157 | * @return string |
| 158 | */ |
| 159 | public function getWordPressHomedir( bool $public = false):string { |
| 160 | if(!$this->_homedir) { |
| 161 | $homedir = function_exists('get_home_path') ? get_home_path() : WP_ROOT; |
| 162 | $this->_homedir = rtrim($homedir, JetBackup::SEP) . JetBackup::SEP; |
| 163 | } |
| 164 | if ($public) return basename($this->_homedir); |
| 165 | return $this->_homedir; |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * @return string |
| 170 | * Returns public restore file location |
| 171 | * Example - |
| 172 | * Alternate path enabled: /home/user/public_html/wp-content/plugins/backup/public/cron |
| 173 | * Alternate path disabled: /home/user/public_html |
| 174 | */ |
| 175 | public function getRestoreFileLocation() : string { |
| 176 | if (Factory::getSettingsRestore()->isRestoreAlternatePathEnabled()) return rtrim(JetBackup::CRON_PATH, JetBackup::SEP); |
| 177 | return rtrim($this->getWordPressHomedir(), JetBackup::SEP); |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * @return string |
| 182 | * Return's WordPress public_dir relative to homedir, needed for nested sites (sites inside subfolders) |
| 183 | * Example |
| 184 | * - getWordPressHomedir: /home/user/sites/www.mydomain.com/subfolder |
| 185 | * - getUserHomedir: /home/user |
| 186 | * - getWordPressRelativePublicDir: /sites/wp2.jetbackup.com/subfolder |
| 187 | */ |
| 188 | public function getWordPressRelativePublicDir() : string { |
| 189 | |
| 190 | $public_dir = trim($this->getWordPressHomedir(), JetBackup::SEP); |
| 191 | $getUserHomedir = trim($this->getUserHomedir(), JetBackup::SEP); |
| 192 | $relative_path = $getUserHomedir; |
| 193 | if ($public_dir != $getUserHomedir && str_starts_with($public_dir, $getUserHomedir)) { |
| 194 | $relative_path = trim(substr($public_dir, strlen($getUserHomedir)), JetBackup::SEP); |
| 195 | } |
| 196 | |
| 197 | return JetBackup::SEP . $relative_path; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * @return string |
| 202 | * Example output: /home/user |
| 203 | */ |
| 204 | |
| 205 | public static function getUserHomedir(): ?string { |
| 206 | |
| 207 | $user_details = Util::getpwuid(Util::geteuid()); |
| 208 | return $user_details['dir'] ?? null; |
| 209 | |
| 210 | } |
| 211 | |
| 212 | public function getUploadDir(): string { |
| 213 | $_uploads = Wordpress::getUploadDir()['basedir'] ?? 'uploads'; |
| 214 | return Wordpress::WP_CONTENT . JetBackup::SEP . basename($_uploads); |
| 215 | } |
| 216 | |
| 217 | public static function validateEmail($email): bool { |
| 218 | // Ensure $email is an array |
| 219 | $emails = is_array($email) ? $email : [$email]; |
| 220 | |
| 221 | foreach ($emails as $singleEmail) { |
| 222 | $sanitizedEmail = Wordpress::sanitizeEmail($singleEmail); |
| 223 | if (!Wordpress::isEmail($sanitizedEmail)) return false; // Invalid email found |
| 224 | } |
| 225 | |
| 226 | return true; |
| 227 | } |
| 228 | |
| 229 | static function getCurrentScreen():?string { |
| 230 | if($screen = Wordpress::getCurrentScreen()) return $screen->id; |
| 231 | return null; |
| 232 | } |
| 233 | |
| 234 | public static function getUserId():?int { |
| 235 | if($user = Wordpress::getCurrentUser()) return $user->ID; |
| 236 | return null; |
| 237 | } |
| 238 | |
| 239 | public static function getUserEmail():?string { |
| 240 | if($user = Wordpress::getCurrentUser()) return $user->user_email; |
| 241 | return null; |
| 242 | } |
| 243 | |
| 244 | public static function getUserIP(): ?string { |
| 245 | $ip = $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? null; |
| 246 | if ($ip === null) return null; |
| 247 | //If forwarded IPs are present, take the first one |
| 248 | if ( Wordpress::strContains( $ip, ',' ) ) {$ip = trim(explode(',', $ip)[0]);} |
| 249 | $ip = Wordpress::sanitizeTextField($ip); |
| 250 | if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip; |
| 251 | return null; |
| 252 | } |
| 253 | |
| 254 | |
| 255 | |
| 256 | public static function isWPCli(): bool { |
| 257 | return (defined('WP_CLI') && WP_CLI); |
| 258 | } |
| 259 | |
| 260 | |
| 261 | public static function isCLI():bool { |
| 262 | |
| 263 | if (isset($_SERVER['HTTP_TE']) || isset($_SERVER['HTTP_COOKIE']) || isset($_SERVER['HTTP_ACCEPT'])) return false; |
| 264 | if(self::isWPCli() || in_array( PHP_SAPI, ['cli', 'cli-server']) || defined('STDIN')) return true; |
| 265 | return isset($_SERVER['argv']) && sizeof($_SERVER['argv']); |
| 266 | |
| 267 | } |
| 268 | } |
| 269 |