__("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 ) ? '': '' ;
$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 = '';
}
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