mirror of
https://gh.wpcy.net/https://github.com/mainwp/mainwp-child.git
synced 2026-04-23 10:32:22 +08:00
377 lines
14 KiB
PHP
377 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* MainWP Child Functions
|
|
*
|
|
* @package MainWP/Child
|
|
*/
|
|
|
|
// Exit if accessed directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
|
|
// phpcs:disable WordPress.Security.NonceVerification
|
|
if ( isset( $_GET['bulk_settings_manageruse_nonce_key'] ) && isset( $_GET['bulk_settings_manageruse_nonce_hmac'] ) ) {
|
|
$bulk_settings_manageruse_nonce_key = ! empty( $_GET['bulk_settings_manageruse_nonce_key'] ) ? intval( $_GET['bulk_settings_manageruse_nonce_key'] ) : '';
|
|
$bulk_settings_manageruse_nonce_hmac = ! empty( $_GET['bulk_settings_manageruse_nonce_hmac'] ) ? wp_unslash( $_GET['bulk_settings_manageruse_nonce_hmac'] ) : ''; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
|
$bulk_settings_managercurrent_time = intval( time() );
|
|
|
|
if ( $bulk_settings_managercurrent_time >= $bulk_settings_manageruse_nonce_key && $bulk_settings_managercurrent_time <= ( $bulk_settings_manageruse_nonce_key + 30 ) && strcmp( $bulk_settings_manageruse_nonce_hmac, hash_hmac( 'sha256', $bulk_settings_manageruse_nonce_key, NONCE_KEY ) ) === 0 && ! function_exists( 'wp_verify_nonce' ) ) :
|
|
/**
|
|
* Verify that correct nonce was used with time limit.
|
|
*
|
|
* The user is given an amount of time to use the token, so therefore, since the
|
|
* UID and $action remain the same, the independent variable is the time.
|
|
*
|
|
* @since 2.0.3
|
|
*
|
|
* @param string $nonce Nonce that was used in the form to verify.
|
|
* @param string|int $action Should give context to what is taking place and be the same when nonce was created.
|
|
*
|
|
* @return false|int False if the nonce is invalid, 1 if the nonce is valid and generated between
|
|
* 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
|
|
*/
|
|
function wp_verify_nonce( $nonce, $action = - 1 ) { //phpcs:ignore -- NOSONAR - multi return.
|
|
$nonce = (string) $nonce;
|
|
$user = wp_get_current_user();
|
|
$uid = (int) $user->ID;
|
|
if ( ! $uid ) {
|
|
/**
|
|
* Filter whether the user who generated the nonce is logged out.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @param int $uid ID of the nonce-owning user.
|
|
* @param string $action The nonce action.
|
|
*/
|
|
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
|
|
}
|
|
|
|
if ( empty( $nonce ) ) {
|
|
|
|
/**
|
|
* To fix verify nonce conflict #1.
|
|
* This is a fake post field to fix some conflict with wp_verify_nonce().
|
|
* Just return false to unverify nonce, does not exit.
|
|
*/
|
|
if ( isset( $_REQUEST[ $action ] ) && ( 'mainwp-bsm-unverify-nonce' === $_REQUEST[ $action ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
// to help trace the conflict with verify nonce in other plugins.
|
|
ob_start();
|
|
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore -- debug feature.
|
|
$stackTrace = "\n" . ob_get_clean();
|
|
|
|
// Invalid nonce.
|
|
if ( isset( $_REQUEST['bulk_settings_skip_invalid_nonce'] ) && ! empty( $_REQUEST['bulk_settings_skip_invalid_nonce'] ) ) {
|
|
return false;
|
|
}
|
|
die( '<mainwp>' . base64_encode( wp_json_encode( array( 'error' => 'You dont send nonce: ' . $action . '<br/>Trace: ' . $stackTrace ) ) ) . '</mainwp>' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions,WordPress.Security.EscapeOutput -- base64_encode function is used for http encode compatible.
|
|
}
|
|
|
|
/**
|
|
* To fix verify nonce conflict #2.
|
|
* This is a fake post field to fix some conflict with wp_verify_nonce().
|
|
* Just return false to unverify nonce, does not exit.
|
|
*/
|
|
if ( 'mainwp-bsm-unverify-nonce' === $nonce ) {
|
|
return false;
|
|
}
|
|
|
|
$token = wp_get_session_token();
|
|
$i = wp_nonce_tick();
|
|
|
|
// Nonce generated 0-12 hours ago.
|
|
$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
|
|
if ( hash_equals( $expected, $nonce ) ) {
|
|
return 1;
|
|
}
|
|
|
|
// Nonce generated 12-24 hours ago.
|
|
$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
|
|
if ( hash_equals( $expected, $nonce ) ) {
|
|
return 2;
|
|
}
|
|
|
|
/**
|
|
* To fix verify nonce conflict #3.
|
|
* This is a fake post field to fix some conflict with wp_verify_nonce().
|
|
* Just return false to unverify nonce, does not exit.
|
|
*/
|
|
if ( isset( $_REQUEST[ $action ] ) && ( 'mainwp-bsm-unverify-nonce' === $_REQUEST[ $action ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
ob_start();
|
|
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore -- debug feature.
|
|
$stackTrace = "\n" . ob_get_clean();
|
|
|
|
// Invalid nonce.
|
|
if ( isset( $_REQUEST['bulk_settings_skip_invalid_nonce'] ) && ! empty( $_REQUEST['bulk_settings_skip_invalid_nonce'] ) ) {
|
|
return false;
|
|
}
|
|
// Invalid nonce.
|
|
die( '<mainwp>' . base64_encode( wp_json_encode( array( 'error' => 'Invalid nonce! Try to use: ' . $action . '<br/>Trace: ' . $stackTrace ) ) ) . '</mainwp>' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions,WordPress.Security.EscapeOutput -- base64_encode function is used for http encode compatible.
|
|
}
|
|
endif;
|
|
}
|
|
|
|
if ( ! function_exists( 'mainwp_child_helper' ) ) {
|
|
|
|
/**
|
|
* Method mainwp_child_helper()
|
|
*
|
|
* Get MainWP Child helper instance.
|
|
*
|
|
* @return mixed MainWP\Child\MainWP_Helper
|
|
*
|
|
* @uses \MainWP\Child\MainWP_Helper::instance()
|
|
*/
|
|
function mainwp_child_helper() {
|
|
return MainWP\Child\MainWP_Helper::instance();
|
|
}
|
|
}
|
|
|
|
if ( ! function_exists( 'mainwp_child_backwpup_wp_list_table_dependency' ) ) {
|
|
|
|
/**
|
|
* Method mainwp_child_backwpup_wp_list_table_dependency()
|
|
*
|
|
* Init backwpupwp list table dependency functions.
|
|
*/
|
|
function mainwp_child_backwpup_wp_list_table_dependency() {
|
|
if ( ! function_exists( 'convert_to_screen' ) ) {
|
|
/**
|
|
* Convert to screen.
|
|
*
|
|
* We need this because BackWPup_Page_Jobs extends WP_List_Table.
|
|
* which uses convert_to_screen.
|
|
*
|
|
* @return MainWP_Fake_Wp_Screen
|
|
*/
|
|
function convert_to_screen() {
|
|
return new MainWP\Child\MainWP_Fake_Wp_Screen();
|
|
}
|
|
}
|
|
|
|
if ( ! function_exists( 'add_screen_option' ) ) {
|
|
/**
|
|
* Adds the WP Fake Screen option.
|
|
*
|
|
* @param mixed $option Options.
|
|
* @param array $args Arguments.
|
|
*/
|
|
function add_screen_option( $option, $args = array() ) {
|
|
unset( $option );
|
|
unset( $args );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! function_exists( 'apply_filters_deprecated' ) ) {
|
|
/**
|
|
* Support old WP version 4.0.
|
|
*
|
|
* Fires functions attached to a deprecated filter hook.
|
|
*
|
|
* When a filter hook is deprecated, the apply_filters() call is replaced with
|
|
* apply_filters_deprecated(), which triggers a deprecation notice and then fires
|
|
* the original filter hook.
|
|
*
|
|
* @param string $hook_name The name of the filter hook.
|
|
* @param array $args Array of additional function arguments to be passed to apply_filters().
|
|
* @param string $version The version of WordPress that deprecated the hook.
|
|
* @param string $replacement Optional. The hook that should have been used. Default empty.
|
|
* @param string $message Optional. A message regarding the change. Default empty.
|
|
*/
|
|
function apply_filters_deprecated( $hook_name, $args, $version, $replacement = '', $message = '' ) {
|
|
if ( ! has_filter( $hook_name ) ) {
|
|
return $args[0];
|
|
}
|
|
do_action( 'deprecated_hook_run', $hook_name, $replacement, $version, $message );
|
|
return apply_filters_ref_array( $hook_name, $args );
|
|
}
|
|
}
|
|
|
|
|
|
if ( ! function_exists( '\mainwp_child_debug_log' ) ) {
|
|
|
|
/**
|
|
* Method mainwp_child_debug_log.
|
|
*
|
|
* @param string $msg Message to log.
|
|
* @return void
|
|
*
|
|
* @since 5.4.1
|
|
*/
|
|
function mainwp_child_debug_log( $msg = '' ) {
|
|
MainWP\Child\MainWP_Helper::log_debug( $msg );
|
|
}
|
|
}
|
|
|
|
|
|
if ( ! function_exists( '\mainwp_child_modules_loader' ) ) {
|
|
|
|
/**
|
|
* Method mainwp_child_modules_loader.
|
|
*
|
|
* @param mixed $class_name
|
|
* @return bool Matched class name.
|
|
*
|
|
* @since 5.4.1
|
|
*/
|
|
function mainwp_child_modules_loader( $class_name ) {
|
|
|
|
$namespaces_modules = array(
|
|
'MainWP\Child\Changes' => 'changes-logs',
|
|
);
|
|
$autoload_dir = rtrim( MAINWP_CHILD_PLUGIN_DIR, DIRECTORY_SEPARATOR );
|
|
foreach ( $namespaces_modules as $base_ns => $mod_dir ) {
|
|
if ( 0 === strpos( $class_name, $base_ns ) ) {
|
|
|
|
$sub_ns = str_replace( $base_ns, '', $class_name );
|
|
|
|
$esc_position = strrchr( $sub_ns, '\\' );
|
|
|
|
if ( false !== $esc_position ) {
|
|
$class_name_no_ns = substr( $esc_position, 1 );
|
|
$sub_dir = str_replace( $class_name_no_ns, '', $sub_ns );
|
|
$sub_dir = str_replace( '\\', '/', $sub_dir );
|
|
|
|
if ( '/' !== $sub_dir ) {
|
|
$sub_dir = trim( $sub_dir, '/' );
|
|
$autoload_path = sprintf( '%s/modules/%s/%s/class-%s.php', $autoload_dir, $mod_dir, strtolower( $sub_dir ), strtolower( str_replace( '_', '-', $class_name_no_ns ) ) );
|
|
} else {
|
|
$autoload_path = sprintf( '%s/modules/%s/classes/class-%s.php', $autoload_dir, $mod_dir, strtolower( str_replace( '_', '-', $class_name_no_ns ) ) );
|
|
}
|
|
if ( file_exists( $autoload_path ) ) {
|
|
require_once $autoload_path; // NOSONAR - WP compatible.
|
|
}
|
|
}
|
|
return true; // class name matched.
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
if ( ! function_exists( '\mainwp_child_is_dashboard_request' ) ) {
|
|
/**
|
|
* True if it is mainwp dashboard request
|
|
*
|
|
* @since 5.4.1
|
|
*
|
|
* @return bool
|
|
*/
|
|
function mainwp_child_is_dashboard_request() {
|
|
return ( isset( $_POST['mainwpsignature'] ) && isset( $_POST['function'] ) ) ? true : false;
|
|
}
|
|
}
|
|
|
|
if ( ! function_exists( '\mainwp_is_rest_api' ) ) {
|
|
/**
|
|
* True if it is frontend
|
|
*
|
|
* @since 5.4.1
|
|
*
|
|
* @return bool
|
|
*/
|
|
function mainwp_is_rest_api() {
|
|
if (
|
|
( defined( 'REST_REQUEST' ) && REST_REQUEST )
|
|
|| ! empty( $_GET['rest_route'] ) // phpcs:ignore
|
|
) {
|
|
return true;
|
|
}
|
|
if ( ! get_option( 'permalink_structure' ) ) {
|
|
return false;
|
|
}
|
|
if ( empty( $GLOBALS['wp_rewrite'] ) ) {
|
|
$GLOBALS['wp_rewrite'] = new \WP_Rewrite(); // phpcs:ignore
|
|
}
|
|
$current_path = trim( (string) parse_url( (string) add_query_arg( array() ), PHP_URL_PATH ), '/' ) . '/'; // phpcs:ignore
|
|
$rest_path = trim( (string) parse_url( (string) get_rest_url(), PHP_URL_PATH ), '/' ) . '/'; // phpcs:ignore
|
|
return strpos( $current_path, $rest_path ) === 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Get main domain using PSL trie
|
|
*
|
|
* @param string $url URL to inspect and extract the registrable domain from.
|
|
*
|
|
* @return string|null Registrable domain (e.g. example.com) or null on failure.
|
|
*/
|
|
function mainwp_get_main_domain( $url ) { //phpcs:ignore --NOSONAR -ok.
|
|
|
|
$url = trim( $url );
|
|
$url = preg_replace( '#^https?://#i', '', $url );
|
|
$host = explode( '/', $url, 2 )[0];
|
|
$host = strtolower( rtrim( $host, '.' ) );
|
|
|
|
if ( ! $host ) {
|
|
return null;
|
|
}
|
|
|
|
$mainwpDir = \MainWP\Child\MainWP_Helper::get_mainwp_dir( 'misc', false, false );
|
|
$cacheDir = $mainwpDir[0];
|
|
|
|
$pslFile = $cacheDir . 'public_suffix_list.dat';
|
|
$pslUrl = 'https://publicsuffix.org/list/public_suffix_list.dat';
|
|
|
|
if ( ! file_exists( $pslFile ) || ( time() - filemtime( $pslFile ) ) > 7 * 24 * 3600 ) {
|
|
// Use WP HTTP API instead of file_get_contents for remote requests.
|
|
$response = wp_remote_get( $pslUrl, array( 'timeout' => 15 ) );
|
|
if ( ! is_wp_error( $response ) ) {
|
|
$code = intval( wp_remote_retrieve_response_code( $response ) );
|
|
$body = wp_remote_retrieve_body( $response );
|
|
if ( $code >= 200 && $code < 300 && ! empty( $body ) ) {
|
|
if ( ! function_exists( 'WP_Filesystem' ) ) {
|
|
require_once ABSPATH . 'wp-admin/includes/file.php'; //phpcs:ignore --NOSONAR -ok.
|
|
}
|
|
global $wp_filesystem;
|
|
if ( empty( $wp_filesystem ) ) {
|
|
WP_Filesystem();
|
|
}
|
|
if ( ! empty( $wp_filesystem ) ) {
|
|
$wp_filesystem->put_contents( $pslFile, $body, FS_CHMOD_FILE );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! file_exists( $pslFile ) ) {
|
|
return null;
|
|
}
|
|
|
|
static $trie = null;
|
|
if ( null === $trie ) {
|
|
require_once MAINWP_CHILD_PLUGIN_DIR . 'includes' . DIRECTORY_SEPARATOR . 'class-psl-trie.php'; //phpcs:ignore --NOSONAR -ok.
|
|
$trie = new PslTrie();
|
|
$lines = file( $pslFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
|
|
foreach ( $lines as $line ) {
|
|
$line = trim( $line );
|
|
if ( '' === $line || 0 === strpos( $line, '//' ) ) {
|
|
continue;
|
|
}
|
|
$trie->insert( $line );
|
|
}
|
|
}
|
|
|
|
$publicSuffix = $trie->find_longest_match( $host );
|
|
$hostParts = explode( '.', $host );
|
|
$suffixParts = explode( '.', $publicSuffix );
|
|
|
|
if ( count( $hostParts ) <= count( $suffixParts ) ) {
|
|
return $host;
|
|
}
|
|
|
|
$registrableParts = array_slice( $hostParts, -count( $suffixParts ) - 1 );
|
|
return implode( '.', $registrableParts );
|
|
}
|