__("Verifying DNS records...", "really-simple-ssl"), 'action'=> 'verify_dns', 'attempts' => 2, 'speed' => 'slow', ), array( 'description' => __("Generating SSL certificate...", "really-simple-ssl"), 'action'=> 'create_bundle_or_renew', 'attempts' => 4, 'speed' => 'slow', ) ); } return $steps; } /** * In case of multisite, we add a step to test for subdomains * @param $steps * * @return mixed */ public function maybe_add_multisite_test($steps){ if (is_multisite() ) { $index = array_search( 'system-status', array_column( $steps['lets-encrypt'], 'id' ) ); $index ++; $steps['lets-encrypt'][ $index ]['actions'] = array_merge( array( array( 'description' => __("Checking for subdomain setup...", "really-simple-ssl"), 'action'=> 'is_subdomain_setup', 'attempts' => 1, 'speed' => 'normal', ) ) , $steps['lets-encrypt'][ $index ]['actions']); } return $steps; } public function catch_settings_switches(){ if ( !rsssl_user_can_manage() ) { return; } /* * reset all option */ if (isset($_GET['reset-letsencrypt'])) { RSSSL_LE()->letsencrypt_handler->clear_order(); delete_option('rsssl_verification_type'); delete_option('rsssl_skip_dns_check' ); delete_option('rsssl_skip_challenge_directory_request' ); delete_option('rsssl_force_plesk' ); delete_option('rsssl_force_cpanel' ); delete_option('rsssl_create_folders_in_root'); delete_option('rsssl_hosting_dashboard'); wp_redirect(rsssl_letsencrypt_wizard_url().'&step=1'); RSSSL_LE()->letsencrypt_handler->clear_keys_directory(); exit; } if (isset($_POST['rsssl-switch-to-dns'])) { update_option('rsssl_verification_type', 'DNS'); $step = $this->step(); rsssl_progress_add('directories'); //if we're in step directories, skip to DNS step if ( $step == 3) { wp_redirect(rsssl_letsencrypt_wizard_url().'&step=4'); exit; } } if (isset($_POST['rsssl-switch-to-directory'])) { delete_option('rsssl_verification_type' ); } if (isset($_POST['rsssl-skip-dns-check'])) { update_option('rsssl_skip_dns_check', true); } if (isset($_POST['rsssl-skip-challenge-directory-request'])) { update_option('rsssl_skip_challenge_directory_request', true); } if (isset($_POST['rsssl-force-plesk'])) { update_option('rsssl_force_plesk', true); } if (isset($_POST['rsssl-force-cpanel'])) { update_option('rsssl_force_cpanel', true); } } /** * * @param $step */ public function installation_progress(){ $step = $this->calculate_next('step'); if (empty($step)) return; $action_list = RSSSL_LE()->config->steps['lets-encrypt'][$step]['actions']; if (count($action_list)==0) return; $actions = array_column($action_list, 'action'); $attempts = array_column($action_list, 'attempts'); $descriptions = array_column($action_list, 'description'); $speed = array_column($action_list, 'speed'); ?>
letsencrypt_handler, $function)) { $error = true; } } if ( !$error ) { if ( function_exists($function) ){ $response = $function(); } else { $response = RSSSL_LE()->letsencrypt_handler->$function(); } $message = $response->message; $action = $response->action; $status = $response->status; $output = $response->output; } $out = array( 'success' => ! $error, 'message' => $message, 'action' => $action, 'status' => $status, 'output' => $output, ); header( "Content-Type: application/json" ); echo json_encode( $out ); exit; } /** * Initialize a page in the wizard * @param $page */ public function initialize( $page ) { $this->last_section = $this->last_section( $page, $this->step() ); $this->page_url = rsssl_letsencrypt_wizard_url(); } /** * Handle some custom options after saving the wizard options * @param string $fieldname * @param mixed $fieldvalue * @param mixed $prev_value * @param string $type */ public function after_save_wizard_option( $fieldname, $fieldvalue, $prev_value, $type ) { //only run when changes have been made if ( $fieldvalue === $prev_value ) { return; } if ( $fieldname==='other_host_type'){ if ( isset(RSSSL_LE()->config->hosts[$fieldvalue]) ){ $dashboard = RSSSL_LE()->config->hosts[$fieldvalue]['hosting_dashboard']; update_option('rsssl_hosting_dashboard', $dashboard); } } if ( $fieldname === 'email_address'&& is_email($fieldvalue) ) { RSSSL_LE()->letsencrypt_handler->update_account($fieldvalue); } } /** * Get the next step with fields in it * @param string $page * @param int $step * * @return int */ public function get_next_not_empty_step( $page, $step ) { if ( ! RSSSL_LE()->field->step_has_fields( $page, $step ) ) { if ( $step >= $this->total_steps( $page ) ) { return $step; } $step ++; $step = $this->get_next_not_empty_step( $page, $step ); } return $step; } /** * Get the next section which is not empty * @param string $page * @param int $step * @param int $section * * @return int|bool */ public function get_next_not_empty_section( $page, $step, $section ) { if ( ! RSSSL_LE()->field->step_has_fields( $page, $step, $section ) ) { //some keys are missing, so we need to count the actual number of keys. if ( isset( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'] ) ) { $n = array_keys( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'] ); //<---- Grab all the keys of your actual array and put in another array $count = array_search( $section, $n ); //<--- Returns the position of the offset from this array using search //this is the actual list up to section key. $new_arr = array_slice( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'], 0, $count + 1, true );//<--- Slice it with the 0 index as start and position+1 as the length parameter. $section_count = count( $new_arr ) + 1; } else { $section_count = $section + 1; } $section ++; if ( $section_count > $this->total_sections( $page, $step ) ) { return false; } $section = $this->get_next_not_empty_section( $page, $step, $section ); } return $section; } /** * Get previous step which is not empty * * @param string $page * @param int $step * * @return int */ public function get_previous_not_empty_step( $page, $step ) { if ( ! RSSSL_LE()->field->step_has_fields( $page, $step ) ) { if ( $step <= 1 ) { return $step; } $step --; $step = $this->get_previous_not_empty_step( $page, $step ); } return $step; } /** * Get previous section which is not empty * @param string $page * @param int $step * @param int $section * * @return false|int */ public function get_previous_not_empty_section( $page, $step, $section ) { if ( ! RSSSL_LE()->field->step_has_fields( $page, $step, $section ) ) { $section --; if ( $section < 1 ) { return false; } $section = $this->get_previous_not_empty_section( $page, $step, $section ); } return $section; } /** * Lock the wizard for further use while it's being edited by the current user. * * * */ public function lock_wizard() { $user_id = get_current_user_id(); set_transient( 'rsssl_wizard_locked_by_user', $user_id, apply_filters( "rsssl_wizard_lock_time", 2 * MINUTE_IN_SECONDS ) ); } /** * Check if the wizard is locked by another user * * * */ public function wizard_is_locked() { $user_id = get_current_user_id(); $lock_user_id = $this->get_lock_user(); if ( $lock_user_id && $lock_user_id != $user_id ) { return true; } return false; } /** * Get user which is locking the wizard * @return false|int */ public function get_lock_user() { return get_transient( 'rsssl_wizard_locked_by_user' ); } /** * Render wizard * @param string $page * @param string $wizard_title */ public function wizard( ) { if (!rsssl_user_can_manage()) { return; } $page = 'lets-encrypt'; if ($this->wizard_is_locked()) { $user_id = $this->get_lock_user(); $user = get_user_by("id", $user_id); $lock_time = apply_filters("rsssl_wizard_lock_time", 2 * MINUTE_IN_SECONDS) / 60; rsssl_notice(sprintf(__("The wizard is currently being edited by %s", 'really-simple-ssl'), $user->user_nicename) . '
' . sprintf(__("If this user stops editing, the lock will expire after %s minutes.", 'really-simple-ssl'), $lock_time), 'warning'); return; } //lock the wizard for other users. $this->lock_wizard(); $this->initialize($page); $step = $this->calculate_next( 'step'); $section = $this->calculate_next('section'); $menu = $this->wizard_menu( $page, '', $step, $section ); $content = $this->wizard_content($page, $step, $section ); $args = array( 'page' => 'lets-encrypt', 'content' => $menu.$content, ); $html = RSSSL()->really_simple_ssl->get_template('admin_wrap.php', $path = rsssl_le_wizard_path, $args ); echo '
'.$html.'
'; } public function calculate_next( $type ){ $step = $this->step(); $section = $this->section(); $page = 'lets-encrypt'; if ($this->section_is_empty($page, $step, $section) || (isset($_POST['rsssl-next']) ) ) { if (RSSSL_LE()->config->has_sections($page, $step) && ($section < $this->last_section) ) { $section++; } else { $step++; $section = $this->first_section($page, $step); } $step = $this->get_next_not_empty_step($page, $step); $section = $this->get_next_not_empty_section($page, $step, $section); //if the last section is also empty, it will return false, so we need to skip the step too. if (!$section) { $section = 1; $step++; } } if (isset($_POST['rsssl-previous'])) { if (RSSSL_LE()->config->has_sections($page, $step) && $section > $this->first_section($page, $step) ) { $section--; } else { $step--; $section = $this->last_section($page, $step); } $step = $this->get_previous_not_empty_step($page, $step); $section = $this->get_previous_not_empty_section($page, $step, $section); } if ($type==='step'){ return $step; } else { return $section; } } /** * Render Wizard menu * @param string $page * @param string $wizard_title * @param int $active_step * @param int $active_section * * @return false|string */ public function wizard_menu( $page, $wizard_title, $active_step, $active_section ) { $args_menu['steps'] = ""; for ($i = 1; $i <= $this->total_steps($page); $i++) { if ($this->step_is_empty($page, $i)) continue; $args['title'] = RSSSL_LE()->config->steps[$page][$i]['title']; $args['active'] = ($i == $active_step) ? 'active' : ''; $args['completed'] = $this->required_fields_completed($page, $i, false) ? 'complete' : 'incomplete'; $args['url'] = '#'; //get id of step based on $i //if this id is in the progress list it has been completed once, we show the url $id = RSSSL_LE()->config->steps['lets-encrypt'][$i]['id']; if ( rsssl_is_ready_for($id) ) { $args['url'] = add_query_arg(array('tab' => 'letsencrypt', 'step' => $i), $this->page_url); } $args['sections'] = ($args['active'] == 'active') ? $this->wizard_sections($page, $active_step, $active_section) : ''; $step_html = RSSSL()->really_simple_ssl->get_template( 'step.php', $path = rsssl_le_wizard_path , $args); $args_menu['steps'] .= $step_html; } $args_menu['percentage-complete'] = $this->wizard_percentage_complete($page, $active_step); $args_menu['title'] = !empty( $wizard_title ) ? '

' . $wizard_title . '

': '' ; $html = RSSSL()->really_simple_ssl->get_template( 'menu.php', $path = rsssl_le_wizard_path, $args_menu ); return $html; } /** * @param string $page * @param int $step * @param int $active_section * * @return string */ public function wizard_sections( $page, $step, $active_section ) { $sections = ""; if ( RSSSL_LE()->config->has_sections( $page, $step )) { for ($i = $this->first_section( $page, $step ); $i <= $this->last_section( $page, $step ); $i ++) { $icon = rsssl_icon('check', 'empty'); if ( $this->section_is_empty( $page, $step, $i ) ) continue; if ( $i < $this->get_next_not_empty_section( $page, $step, $i ) ) continue; $active = ( $i == $active_section ) ? 'active' : ''; if ( $active == 'active' ) { $icon = rsssl_icon('arrow-right-alt2', 'success'); } else if ($this->required_fields_completed( $page, $step, $i )) { $icon = rsssl_icon('check', 'success'); } $completed = ( $this->required_fields_completed( $page, $step, $i ) ) ? "rsssl-done" : "rsssl-to-do"; $url = add_query_arg( array('tab' => 'letsencrypt', 'step' => $step, 'section' => $i), $this->page_url ); $title = RSSSL_LE()->config->steps[ $page ][ $step ]['sections'][ $i ]['title']; $args = array( 'active' => $active, 'completed' => $completed, 'icon' => $icon, 'url' => $url, 'title' => $title, ); $section_html = RSSSL()->really_simple_ssl->get_template( 'section.php', $path = rsssl_le_wizard_path, $args ); $sections .= $section_html; } } return $sections; } /** * Render wizard content * @param string $page * @param int $step * @param int $section * * @return false|string */ public function wizard_content( $page, $step, $section ) { $args = array( 'save_notice' => '', 'previous_button' => '', 'next_button' => '', 'save_button' => '', 'intro' => $this->get_intro( $page, $step, $section ), 'page_url' => $this->page_url, 'page' => $page, 'step' => $step, 'section' => $section, ); if (isset(RSSSL_LE()->config->steps[$page][$step]['sections'][$section]['title'])) { $args['title'] = RSSSL_LE()->config->steps[$page][$step]['sections'][$section]['title']; } else { $args['title'] = RSSSL_LE()->config->steps[$page][$step]['title']; } ob_start(); RSSSL_LE()->field->get_fields( $page, $step, $section ); $args['fields'] = ob_get_clean(); if ( $step > 1 || $section > 1 ) { $args['previous_button'] = ''; } if ( $step < $this->total_steps( $page ) ) { $action_list = RSSSL_LE()->config->steps['lets-encrypt'][$step]['actions']; $disabled = ''; if ( count($action_list)>0 ) { $disabled = 'disabled'; } $args['next_button'] = ''; } if ( $step > 0 && $step < $this->total_steps( $page )) { $args['save_button'] = RSSSL_LE()->field->save_button(); } elseif ($step === $this->total_steps( $page )) { $args['save_button'] = $this->activate_ssl_buttons(); } $html = RSSSL()->really_simple_ssl->get_template( 'content.php', $path = rsssl_le_wizard_path, $args ); return $html; } /** * @deprecated * @return string */ public function get_support_url() { $user_info = get_userdata(get_current_user_id()); $email = urlencode($user_info->user_email); $name = urlencode($user_info->display_name); $verification_type = get_option('rsssl_verification_type') === 'DNS' ? 'DNS' : 'DIR'; $skip_dns_check = get_option('rsssl_skip_dns_check' ) ? 'Skip DNS check' : 'Do DNS check'; $skip_directory_check = get_option('rsssl_skip_challenge_directory_request' ) ? 'Skip directory check' : 'Do directory check'; $hosting_company = rsssl_get_other_host(); $dashboard = 'unknown'; if (rsssl_is_cpanel()){ $dashboard = 'cpanel'; } else if(rsssl_is_plesk()){ $dashboard = 'plesk'; } else if (rsssl_is_directadmin()){ $dashboard = 'directadmin'; } $debug_log_contents = RSSSL()->really_simple_ssl->debug_log; $debug_log_contents = str_replace("\n", '--br--', $debug_log_contents ); $debug_log_contents .= 'dashboard '.$dashboard.'--br--'; $debug_log_contents .= 'skip dns check '.$skip_dns_check.'--br--'; $debug_log_contents .= 'skip directory check '.$skip_directory_check.'--br--'; $debug_log_contents .= 'verification type '.$verification_type.'--br--'; $debug_log_contents = urlencode(strip_tags( $debug_log_contents ) ); //Retrieve the domain $domain = site_url(); $url = "https://really-simple-ssl.com/letsencrypt-support/?email=$email&customername=$name&domain=$domain&hosting_company=$hosting_company&debuglog=$debug_log_contents"; return $url; } public function activate_ssl_buttons(){ ob_start(); wp_nonce_field('rsssl_le_nonce', 'rsssl_le_nonce'); ?> letsencrypt_handler->certificate_status(); $certificate_is_valid = $response->status === 'error'; $already_enabled = RSSSL()->really_simple_ssl->ssl_enabled; if ($certificate_is_valid && $already_enabled){ ?> "rlrsssl_really_simple_ssl"),admin_url("options-general.php") ) );?>"> " id="rsssl_do_activate_ssl" name="rsssl_do_activate_ssl"> " id="rsssl_recheck_ssl" name="rsssl_recheck_ssl"> get_next_not_empty_section( $page, $step, $section ); if ( $section != $section_compare ) { return true; } return false; } public function step_is_empty( $page, $step ) { $step_compare = $this->get_next_not_empty_step( $page, $step ); if ( $step != $step_compare ) { return true; } return false; } /** * Enqueue assets * @param $hook */ public function enqueue_assets( $hook ) { if (!isset($_GET['tab']) || $_GET['tab']!=='letsencrypt') return; $minified = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; wp_register_style( 'select2', rsssl_le_url . 'wizard/assets/select2/css/select2.min.css', false, rsssl_version ); wp_enqueue_style( 'select2' ); wp_enqueue_script( 'select2', rsssl_le_url . "wizard/assets/select2/js/select2.min.js", array( 'jquery' ), rsssl_version, true ); // Let's encrypt wp_register_style( 'rsssl-wizard', rsssl_le_url . "wizard/assets/css/wizard$minified.css", false, rsssl_version ); wp_enqueue_style( 'rsssl-wizard' ); // @todo admin css in wizard.less wp_register_style( 'rsssl-wizard-admin', rsssl_le_url . "wizard/assets/css/admin$minified.css", false, rsssl_version ); wp_enqueue_style( 'rsssl-wizard-admin' ); wp_enqueue_script( 'rsssl-wizard', rsssl_le_url . "wizard/assets/js/wizard$minified.js", array( 'jquery', 'select2' ), rsssl_version.time(), true ); wp_localize_script( 'rsssl-wizard', 'rsssl_wizard', array( 'admin_url' => admin_url( 'admin-ajax.php' ), 'no_results' => __("I don't know, or not listed, proceed with installation","really-simple-ssl"), ) ); } /** * Foreach required field, check if it's been answered * if section is false, check all fields of the step. * @param string $page * @param int $step * @param int $section * * @return bool */ public function required_fields_completed( $page, $step, $section ) { //get all required fields for this section, and check if they're filled in $fields = RSSSL_LE()->config->fields( $page, $step, $section ); $fields = rsssl_array_filter_multidimensional( $fields, 'required', true ); foreach ( $fields as $fieldname => $args ) { //if a condition exists, only check for this field if the condition applies. if ( isset( $args['condition'] ) || isset( $args['callback_condition'] ) && ! RSSSL_LE()->field->condition_applies( $args ) ) { continue; } $value = RSSSL_LE()->field->get_value( $fieldname ); if ( empty( $value ) ) { return false; } } return true; } public function all_required_fields_completed_wizard(){ return $this->all_required_fields_completed('lets-encrypt'); } /** * Check if all required fields are filled * @return bool * * */ public function all_required_fields_completed( $page ) { for ( $step = 1; $step <= $this->total_steps( $page ); $step ++ ) { if ( RSSSL_LE()->config->has_sections( $page, $step ) ) { for ( $section = $this->first_section( $page, $step ); $section <= $this->last_section( $page, $step ); $section ++ ) { if ( ! $this->required_fields_completed( $page, $step, $section ) ) { return false; } } } else { if ( ! $this->required_fields_completed( $page, $step, false ) ) { return false; } } } return true; } /** * Get a notice style header with an intro above a step or section * * @param string $page * @param int $step * @param int $section * * @return string */ public function get_intro( $page, $step, $section ) { //only show when in action $intro = ''; if ( RSSSL_LE()->config->has_sections( $page, $step ) ) { if ( isset( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'][ $section ]['intro'] ) ) { $intro .= RSSSL_LE()->config->steps[ $page ][ $step ]['sections'][ $section ]['intro']; } } else { if ( isset( RSSSL_LE()->config->steps[ $page ][ $step ]['intro'] ) ) { $intro .= RSSSL_LE()->config->steps[ $page ][ $step ]['intro']; } } if ( strlen( $intro ) > 0 ) { $intro = '
' . $intro . '
'; } return $intro; } public function get_type( $post_id = false ) { $page = false; if ( $post_id ) { $post_type = get_post_type( $post_id ); $page = str_replace( 'rsssl-', '', $post_type ); } if ( isset( $_GET['page'] ) ) { $page = str_replace( 'rsssl-', '', sanitize_title( $_GET['page'] ) ); } return $page; } public function step( $page = false ) { $step = 1; if ( ! $page ) { $page = 'lets-encrypt'; } $total_steps = $this->total_steps( $page ); if ( isset( $_GET["step"] ) ) { $step = intval( $_GET['step'] ); } if ( isset( $_POST["step"] ) ) { $step = intval( $_POST['step'] ); } if ( $step > $total_steps ) { $step = $total_steps; } if ( $step <= 1 ) { $step = 1; } return $step; } public function section() { $section = 1; if ( isset( $_GET["section"] ) ) { $section = intval( $_GET['section'] ); } if ( isset( $_POST["section"] ) ) { $section = intval( $_POST['section'] ); } if ( $section > $this->last_section ) { $section = $this->last_section; } if ( $section <= 1 ) { $section = 1; } return $section; } /** * Get total number of steps for a page * * @param $page * * @return int */ public function total_steps( $page ) { return count( RSSSL_LE()->config->steps[ $page ] ); } public function total_sections( $page, $step ) { if ( ! isset( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'] ) ) { return 0; } return count( RSSSL_LE()->config->steps[ $page ][ $step ]['sections'] ); } public function last_section( $page, $step ) { if ( ! isset( RSSSL_LE()->config->steps[ $page ][ $step ]["sections"] ) ) { return 1; } $array = RSSSL_LE()->config->steps[ $page ][ $step ]["sections"]; return max( array_keys( $array ) ); } public function first_section( $page, $step ) { if ( ! isset( RSSSL_LE()->config->steps[ $page ][ $step ]["sections"] ) ) { return 1; } $arr = RSSSL_LE()->config->steps[ $page ][ $step ]["sections"]; $first_key = key( $arr ); return $first_key; } /** * * Check which percentage of the wizard is completed * @param bool $count_warnings * * @return int * */ public function wizard_percentage_complete( $page, $step ) { //store to make sure it only runs once. if ( $this->percentage_complete !== false ) { return $this->percentage_complete; } $total_steps = $this->total_steps( 'lets-encrypt' ); $percentage = round( 100 * ( $step / $total_steps ) + 0.45 ); $this->percentage_complete = $percentage; return $percentage; } } } //class closure