format("Y/m/d h:i:s"); // Convert arrays and objects to JSON format if (is_array($data) || is_object($data)) { $data = json_encode($data, JSON_PRETTY_PRINT); $message = $message . "\r\n" . $data; } else if ($data) { $message = $message . " " . $data; } // Include backtrace information if enabled if ($enable_backtrace) { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $callingFunction = $backtrace[1]['function']; // Access the calling function name $backtrace_info = json_encode($backtrace, JSON_PRETTY_PRINT); $message .= "\r\nBacktrace:\r\n" . $backtrace_info; } error_log("[$date] " . $message . "\r\n", 3, $log_File); } } function action_log($message, $data = null, $enable_backtrace = false) { if ($message) { $log_File = ACTION_LOG; $date = new DateTime('now', new DateTimeZone('America/Chicago')); $date = $date->format("Y/m/d h:i:s"); // Convert arrays and objects to JSON format if (is_array($data) || is_object($data)) { $data = json_encode($data, JSON_PRETTY_PRINT); $message = $message . "\r\n" . $data; } else if ($data) { $message = $message . " " . $data; } // Include backtrace information if enabled if ($enable_backtrace) { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $callingFunction = $backtrace[1]['function']; // Access the calling function name $backtrace_info = json_encode($backtrace, JSON_PRETTY_PRINT); $message .= "\r\nBacktrace:\r\n" . $backtrace_info; } error_log("[$date] " . $message . "\r\n", 3, $log_File); } } function rl_mailwarmer_enqueue_scripts() { wp_enqueue_script('jquery'); wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-tabs'); wp_enqueue_style('jquery-ui-css', 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/themes/base/jquery-ui.min.css'); wp_add_inline_script('jquery', ' jQuery(document).ready(function($) { $(".notice-dismiss").on("click", function() { $(this).closest(".notice").fadeOut(); }); $(".advanced-toggle").click(function() { $(".advanced-content").slideToggle(); $(this).toggleClass("open"); }); }); '); wp_enqueue_script('rl-mailwarmer-public-script', RL_MAILWARMER_URL . '/js/public-check-domain-health.js', ['jquery'], null, true); wp_localize_script('rl-mailwarmer-public-script', 'rlMailWarmer_public', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('check_domain_health_nonce'), 'post_id' => get_the_ID() ]); } add_action('wp_enqueue_scripts', 'rl_mailwarmer_enqueue_scripts'); /** * Disable specific plugins based on the WP_ENVIRONMENT_TYPE */ function disable_plugins_based_on_environment() { // log_to_file("disable_plugins_based_on_environment - Disabling plugins"); // Ensure the environment type is defined if ( ! defined( 'WP_ENVIRONMENT_TYPE' ) ) { return; } // Retrieve the environment type $environment = WP_ENVIRONMENT_TYPE; // log_to_file("disable_plugins_based_on_environment - Disabling plugins for $environment environment"); // Define plugins to disable based on environment in wp-config.php $disabled_plugins = defined( 'DISABLED_PLUGINS' ) ? DISABLED_PLUGINS : array(); // Only proceed if the array is properly defined and not empty if ( ! is_array( $disabled_plugins ) || empty( $disabled_plugins ) ) { return; } // Get the currently active plugins $active_plugins = get_option( 'active_plugins', array() ); foreach ( $disabled_plugins as $plugin_env => $plugins ) { // Skip if current environment doesn't match if ( $environment !== $plugin_env ) { continue; } // Loop through plugins to disable for this environment foreach ( $plugins as $plugin ) { $plugin_key = array_search( $plugin, $active_plugins, true ); // If the plugin is active, deactivate it if ( false !== $plugin_key ) { unset( $active_plugins[ $plugin_key ] ); } } } // Update the active plugins option update_option( 'active_plugins', $active_plugins ); } add_action( 'plugins_loaded', 'disable_plugins_based_on_environment', 1 ); /** * getRandomWeightedElement() * Utility function for getting random values with weighting. * Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50) * An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%. * The return value is the array key, A, B, or C in this case. Note that the values assigned * do not have to be percentages. The values are simply relative to each other. If one value * weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66% * chance of being selected. Also note that weights should be integers. * * @param array $weightedValues */ function getRandomWeightedElement(array $weightedValues) { $rand = mt_rand(1, (int) array_sum($weightedValues)); foreach ($weightedValues as $key => $value) { $rand -= $value; if ($rand <= 0) { return $key; } } } /** * Retrieve the content of a textarea meta field and return it as an array if it's a comma-separated list or has multiple lines. * * @param int $post_id The ID of the post. * @param string $meta_key The meta key to retrieve. * @return array|string The processed array or the original string if no transformation is needed. */ function rl_get_textarea_meta_as_array($post_id, $meta_key) { if ($post_id ==='option') { $content = get_option('options_' . $meta_key); } else { $content = get_post_meta($post_id, $meta_key, true); } // log_to_file("rl_get_textarea_meta_as_array - Content {$content}"); if (empty($content)) { // log_to_file("rl_get_textarea_meta_as_array - {$meta_key} field not found for {$post_id}"); return []; // Return an empty array if the meta field is empty } // Check if the content contains multiple lines or is comma-separated if (strpos($content, "\n") !== false || strpos($content, ',') !== false) { // Normalize line breaks and split the content into an array $content_array = preg_split('/[\r\n,]+/', $content); // Remove empty entries and trim whitespace return array_filter(array_map('trim', $content_array)); } return $content; // Return the original content if no transformation is needed } /** * * Unset default dashboard widgets * */ function remove_dashboard_widgets() { global $wp_meta_boxes; unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now']); unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity']); unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_quick_press']); unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_primary']); // unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links']); // unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins']); // unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_drafts']); // unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments']); // unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_secondary']); // unset($wp_meta_boxes['dashboard']['normal']['high']['rank_math_dashboard_widget']); } add_action('wp_dashboard_setup', 'remove_dashboard_widgets' ); /** * * Reorder the admin menu. Leaves positions 1-8 available * */ add_action('admin_head', 'mf_edit_admin_menu'); function mf_edit_admin_menu(){ global $menu; $menu[0] = $menu[2]; // Move the Dashboard to the top unset($menu[2]); // Unset the Dashboard (from original position) // $menu[8] = $menu[4]; // Copy 'separator1' to a new menu location unset($menu[4]); // Unset separator1 (from original position) ///$menu[9] = $menu[5]; // Copy 'Posts' to a new menu location unset($menu[5]); // Unset Posts (from original position) ksort($menu); // Sort the menu } /** * Append Login In/Out link to menu with a redirect to this page */ add_filter( 'wp_nav_menu_primary-menu_items','rl_mailwarmer_loginout_menu_link', 10, 1 ); function rl_mailwarmer_loginout_menu_link( $menu ) { $referrer_url = $_SERVER['REQUEST_URI']; // $redirect_url = "/membership-levels"; $redirect_url = "/dashboard"; // log_to_file("referrer_url: $referrer_url"); // if ($referrer_url == '/membership-levels/') { // $redirect_url = "/dashboard"; // } $loginout = wp_loginout( $redirect_url, false ); $menu .= $loginout; return $menu; } // Create a shortcode to match add_shortcode( 'mailferno_login_link', 'mailferno_show_login_link' ); function mailferno_show_login_link( ) { $referrer_url = $_SERVER['REQUEST_URI']; // $redirect_url = "/membership-levels"; $redirect_url = "/dashboard/?redirect_to=%2Fdashboard"; // log_to_file("referrer_url: $referrer_url"); // if ($referrer_url == '/membership-levels/') { // $redirect_url = "/dashboard"; // } $login = 'Already have an account? Login here!'; return $login; } /** * Add a meta box for testing the SSH connection. */ add_action('add_meta_boxes', function () { add_meta_box( 'test_ssh_connection_box', __('Test SSH Connection', 'rl-mailwarmer'), 'rl_mailwarmer_render_test_ssh_connection_box', 'server', 'side', 'default' ); }); /** * Render the SSH connection test meta box. * * @param WP_Post $post The current post object. */ function rl_mailwarmer_render_test_ssh_connection_box($post) { // Add a nonce field for security wp_nonce_field('test_ssh_connection_nonce', 'test_ssh_connection_nonce_field'); // Render the button ?>

post_type === 'server') { wp_enqueue_script( 'rl-mailwarmer-test-ssh-js', RL_MAILWARMER_URL . 'js/test-ssh-connection.js', // Adjust path as needed ['jquery'], null, true ); wp_localize_script('rl-mailwarmer-test-ssh-js', 'rlMailWarmerTestSSH', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('test_ssh_connection_nonce'), 'post_id' => $post->ID ]); } }); add_action('wp_ajax_rl_mailwarmer_test_ssh_connection', function () { // Verify nonce if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'test_ssh_connection_nonce')) { wp_send_json_error(__('Invalid nonce', 'rl-mailwarmer')); } // Validate and sanitize input $post_id = intval($_POST['post_id']); if (!$post_id || get_post_type($post_id) !== 'server') { wp_send_json_error(__('Invalid server ID.', 'rl-mailwarmer')); } // Fetch server details $server_ip = get_post_meta($post_id, 'ip_address', true); $server_port = get_post_meta($post_id, 'ssh_port', true); $server_user = get_post_meta($post_id, 'username', true); $server_key = get_post_meta($post_id, 'ssh_private_key', true); // log_to_file("wp_ajax_rl_mailwarmer_test_ssh_connection - SSH $server_user $server_ip $server_port"); // log_to_file("wp_ajax_rl_mailwarmer_test_ssh_connection - SSH Private Key: $server_key"); if (empty($server_ip) || empty($server_user) || empty($server_key)) { wp_send_json_error(__('Missing server credentials.', 'rl-mailwarmer')); } // Test SSH connection try { $ssh = new phpseclib3\Net\SSH2($server_ip, $server_port); $key = phpseclib3\Crypt\PublicKeyLoader::loadPrivateKey($server_key); if (!$ssh->login($server_user, $key)) { throw new Exception(__('SSH login failed.', 'rl-mailwarmer')); } wp_send_json_success(__('SSH connection successful.', 'rl-mailwarmer')); } catch (Exception $e) { wp_send_json_error($e->getMessage()); } }); /** * Add sidebars to custom post types * */ function register_custom_sidebars() { register_sidebar(array( 'name' => 'Domain Sidebar', 'id' => 'sidebar-domain', 'description' => 'Sidebar for domain post type', 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

' )); register_sidebar(array( 'name' => 'Email Address Sidebar', 'id' => 'sidebar-email', 'description' => 'Sidebar for email-address post type', 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

' )); register_sidebar(array( 'name' => 'Campaign Sidebar', 'id' => 'sidebar-campaign', 'description' => 'Sidebar for campaign post type', 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

' )); } add_action('widgets_init', 'register_custom_sidebars'); // add_filter( 'generate_sidebar_layout','rl_mailwarmer_custom_sidebar_layout' ); function rl_mailwarmer_custom_sidebar_layout( $layout ) { $post_type = get_post_type(); // log_to_file("rl_mailwarmer_custom_sidebar_layout - Setting custom sidebar for $post_type post.", $layout); switch ($post_type) { case 'domain': $layout = 'sidebar-domain'; break; case 'email-address': $layout = 'sidebar-email'; break; case 'campaign': $layout = 'sidebar-campaign'; break; default: // return $layout; break; } // log_to_file("rl_mailwarmer_custom_sidebar_layout - Setting custom sidebar for $post_type post to: $layout"); // Or else, set the regular layout return $layout; } /** * PaidMemberships Pro Customizations * */ /** * Redirects members-only content to the Membership Levels page if a user is logged out or not a member. * */ add_action( 'template_redirect', 'rl_mailwarmer_redirect_require_membership_access' ); function rl_mailwarmer_redirect_require_membership_access() { if ( function_exists( 'pmpro_has_membership_access' ) && ! pmpro_has_membership_access() ) { wp_redirect( pmpro_url( 'login' ) ); exit; } } /** * Add our user fields: cloudflare_api_email, cloudflare_api_key. * This callback fires during the init action hook. */ function mailferno_pmpro_add_user_fields() { // Don't break if PMPro is out of date or not loaded. if ( ! function_exists( 'pmpro_add_user_field' ) ) { return false; } // Store our field settings in an array. $fields = array(); /* Settings for a company text field that is shown in the user profile. The text field has a custom size and CSS class. It is required. Only members with or checking out for levels 1 and 2 will see the field. */ $fields[] = new PMPro_Field( 'cloudflare_api_email', // input name and user meta key 'text', // type of field array( 'label' => 'CloudFlare API Email', // custom field label // 'size' => 40, // input size 'class' => 'company', // custom class 'profile' => true, // show in user profile // 'required' => true, // make this field required // 'levels' => array(1,2), // require level 1 or 2 for this field 'memberslistcsv' => true // include in CSV export ) ); /* Settings for a referral code field. All users can set this at checkout. Only admins can see it on the user profile page. */ $fields[] = new PMPro_Field( 'cloudflare_api_key', // input name and user meta key key 'text', // type of field array( 'label' => 'CloudFlare API Key', // custom field label 'profile' => true, // only show in profile for admins 'memberslistcsv' => true // include in CSV export ) ); // Add a field group to put our fields into. pmpro_add_field_group( 'CloudFlare API Settings' ); // Add all of our fields into that group. foreach ( $fields as $field ) { pmpro_add_user_field( 'CloudFlare API Settings', // Which group to add to. $field // PMPro_Field object ); } // That's it. See the PMPro User Fields docs for more information. } add_action( 'init', 'mailferno_pmpro_add_user_fields' ); /** * Allow users to delete posts that they own * */ // Handle front-end deletions function handle_frontend_post_deletion() { if ( isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['post']) && isset($_GET['_wpnonce']) ) { $post_id = intval($_GET['post']); // Verify nonce if (!wp_verify_nonce($_GET['_wpnonce'], 'delete-post_' . $post_id)) { wp_die('Security check failed'); } // Check permissions if (!can_delete_post($post_id)) { wp_die('You do not have permission to delete this item'); } // Delete the post wp_delete_post($post_id, true); // Redirect back $redirect_to = isset($_GET['redirect_to']) ? urldecode($_GET['redirect_to']) : ''; if (empty($redirect_to)) { $redirect_to = remove_query_arg(array('action', 'post', '_wpnonce')); } wp_redirect(add_query_arg('deleted', '1', $redirect_to)); exit; } } add_action('template_redirect', 'handle_frontend_post_deletion'); // Check if the user is the owner (for non-admins) function can_delete_post($post_id) { if (current_user_can('administrator')) { return true; } $current_user_id = get_current_user_id(); $post_owner_id = get_post_meta($post_id, 'owner_id', true); return $current_user_id == $post_owner_id; } // Single Domain View function get_connection_status($credentials) { if ($credentials === false) return "Error"; $missing = []; foreach (['api_email', 'api_key', 'zone_id'] as $key) { if (empty($credentials[$key])) $missing[] = $key; } return empty($missing) ? "Connected" : "Missing: " . implode(", ", $missing); } function mask_api_key($key) { if (empty($key)) return ""; return str_repeat("*", strlen($key) - 6) . substr($key, -6); }