/** * Auto setup settings. * * Fires after a membership setup is completed. * This hook is executed every time a new membership is created. * * Related Action Hooks: * - ms_controller_membership_setup_completed * * @since 1.0.0 * * @param MS_Model_Membership $membership */ public function auto_setup_settings($membership) { $settings = $this->get_model(); // Create special pages. MS_Model_Pages::create_missing_pages(); $pg_prot_cont = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_PROTECTED_CONTENT); $pg_acco = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_ACCOUNT); $pg_regi = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_REGISTER); $pg_regi_comp = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_REG_COMPLETE); $pg_memb = MS_Model_Pages::get_page(MS_Model_Pages::MS_PAGE_MEMBERSHIPS); // Publish special pages. // Tip: Only pages must be published that are added to the menu. wp_publish_post($pg_acco->ID); if (!$membership->private) { wp_publish_post($pg_memb->ID); wp_publish_post($pg_regi->ID); } // Create new WordPress menu-items. MS_Model_Pages::create_menu(MS_Model_Pages::MS_PAGE_ACCOUNT); if (!$membership->private) { MS_Model_Pages::create_menu(MS_Model_Pages::MS_PAGE_MEMBERSHIPS); MS_Model_Pages::create_menu(MS_Model_Pages::MS_PAGE_REGISTER); } // Enable Membership2. $settings->plugin_enabled = true; $settings->save(); // Enable the "Allow user registration" setting of WordPress MS_Model_Member::allow_registration(); }
/** * Ajax handler. Used by shortcode `ms-membership-login` to recover password * * @since 1.0.0 * @access public */ public function ajax_lostpass() { global $wpdb, $wp_hasher; $resp = array(); // First check the nonce, if it fails the function will break check_ajax_referer('ms-ajax-lostpass'); // Nonce is checked, get the POST data and sign user on $errors = new WP_Error(); if (empty($_POST['user_login'])) { $resp['error'] = __('Enter a username or e-mail address.', MS_TEXT_DOMAIN); } else { if (strpos($_POST['user_login'], '@')) { $user_data = get_user_by('email', trim($_POST['user_login'])); if (empty($user_data)) { $resp['error'] = __('There is no user registered with that email address.', MS_TEXT_DOMAIN); } } else { $login = trim($_POST['user_login']); $user_data = get_user_by('login', $login); } } do_action('lostpassword_post'); if (!empty($resp['error'])) { $this->respond($resp); } if (!$user_data) { $resp['error'] = __('Invalid username or e-mail.', MS_TEXT_DOMAIN); $this->respond($resp); } // Redefining user_login ensures we return the right case in the email. $user_login = $user_data->user_login; $user_email = $user_data->user_email; do_action('retreive_password', $user_login); // Legacy (misspelled) do_action('retrieve_password', $user_login); $allow = apply_filters('allow_password_reset', true, $user_data->ID); if (!$allow) { $resp['error'] = __('Password reset is not allowed for this user', MS_TEXT_DOMAIN); $this->respond($resp); } else { if (is_wp_error($allow)) { return $allow; } } // Generate something random for a password reset key. $key = wp_generate_password(20, false); do_action('retrieve_password_key', $user_login, $key); // Now insert the key, hashed, into the DB. if (empty($wp_hasher)) { require_once ABSPATH . WPINC . '/class-phpass.php'; $wp_hasher = new PasswordHash(8, true); } $hashed = $wp_hasher->HashPassword($key); $wpdb->update($wpdb->users, array('user_activation_key' => $hashed), array('user_login' => $user_login)); MS_Model_Pages::create_missing_pages(); $reset_url = MS_Model_Pages::get_page_url(MS_Model_Pages::MS_PAGE_ACCOUNT); $reset_url = esc_url_raw(add_query_arg(array('action' => MS_Controller_Frontend::ACTION_VIEW_RESETPASS, 'key' => $key, 'login' => rawurlencode($user_login)), $reset_url)); $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n"; $message .= network_home_url('/') . "\r\n\r\n"; $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n"; $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; $message .= '<' . $reset_url . ">\r\n"; if (is_multisite()) { $blogname = $GLOBALS['current_site']->site_name; } else { $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); } $title = sprintf(__('[%s] Password Reset'), $blogname); $title = apply_filters('retrieve_password_title', $title); $message = apply_filters('retrieve_password_message', $message, $key, $reset_url); if ($message && !wp_mail($user_email, wp_specialchars_decode($title), $message)) { $resp['error'] = __('The e-mail could not be sent.') . '<br />' . __('Possible reason: your host may have disabled the mail() function.'); } else { $resp['success'] = __('Check your e-mail for the confirmation link.', MS_TEXT_DOMAIN); } $this->respond($resp); }
/** * Creates a new password-reset key and stores it in the DB. * * @since 1.0.2.3 * @return object { * The reset-key that can be sent to the user. * * @var key The reset key * @var url The full reset URL * } */ public function new_password_reset_key() { global $wpdb, $wp_hasher; // Generate something random for a password reset key. $key = wp_generate_password(20, false); do_action('retrieve_password_key', $this->username, $key); // Now insert a hashed version of the key into the DB. // Important: The has needs to include the time() value! if (empty($wp_hasher)) { require_once ABSPATH . WPINC . '/class-phpass.php'; $wp_hasher = new PasswordHash(8, true); } $hashed = time() . ':' . $wp_hasher->HashPassword($key); $wpdb->update($wpdb->users, array('user_activation_key' => $hashed), array('user_login' => $this->username)); MS_Model_Pages::create_missing_pages(); $reset_url = MS_Model_Pages::get_page_url(MS_Model_Pages::MS_PAGE_ACCOUNT); $reset_url = esc_url_raw(add_query_arg(array('action' => MS_Controller_Frontend::ACTION_VIEW_RESETPASS, 'key' => $key, 'login' => rawurlencode($this->username)), $reset_url)); return (object) array('key' => $key, 'url' => $reset_url); }
/** * Upgrade database. * * @since 1.0.0 * @param bool $force Also execute update logic when version did not change. */ public static function update($force = false) { static $Done = false; if ($Done && !$force) { return; } // Migration handler has its own valid_user check. self::check_migration_handler(); // Updates are only triggered from Admin-Side by an Admin user. if (!self::valid_user()) { return; } // Check for correct network-wide protection setup. self::check_settings(); $settings = MS_Factory::load('MS_Model_Settings'); $old_version = $settings->version; // Old: The version in DB. $new_version = MS_Plugin::instance()->version; // New: Version in file. $is_new_setup = empty($old_version); // Compare current src version to DB version: // We only do UP-grades but no DOWN-grades! if ($old_version) { $version_changed = version_compare($old_version, $new_version, 'lt'); } else { $version_changed = true; } if ($force || $version_changed) { $Done = true; $msg = array(); /* * ----- General update logic, executed on every update ------------ */ do_action('ms_model_upgrade_before_update', $settings, $old_version, $new_version, $force); // Prepare the Update message. if (!$version_changed) { $msg[] = sprintf(__('<strong>Membership 2</strong> is set up for version %1$s!', 'membership2'), $new_version); } else { $msg[] = sprintf(__('<strong>Membership 2</strong> was updated to version %1$s!', 'membership2'), $new_version); } // Every time the plugin is updated we clear the cache. MS_Factory::clear(); // Create missing Membership pages. $new_pages = MS_Model_Pages::create_missing_pages(); if (!empty($new_pages)) { $msg[] = sprintf(__('New Membership pages created: "%1$s".', 'membership2'), implode('", "', $new_pages)); } // Remove an old version of Protected Content // TODO: REMOVE THIS BLOCK/FUNCTION END OF 2015 if ($version_changed) { self::remove_old_copy(); } // Note: We do not create menu items on upgrade! Users might have // intentionally removed the items from the menu... /* * ----- Version-Specific update logic ----------------------------- */ // Upgrade from a 1.0.0.x version to 1.0.1.0 or higher if (version_compare($old_version, '1.0.1.0', 'lt')) { self::_upgrade_1_0_1_0(); } // Upgrade from 1.0.1.0 version to 1.0.1.1 or higher if (version_compare($old_version, '1.0.1.1', 'lt')) { self::_upgrade_1_0_1_1(); } // Upgrade from 1.0.1.x version to 1.0.2.0 or higher if (version_compare($old_version, '1.0.2.0', 'lt')) { self::_upgrade_1_0_2_0(); } // Upgrade from 1.0.2.x version to 1.0.2.4 or higher if (version_compare($old_version, '1.0.2.4', 'lt')) { self::_upgrade_1_0_2_4(); } /* * ----- General update logic, executed on every update ------------ */ $settings->version = $new_version; $settings->save(); // Display a message after the page is reloaded. if (!$is_new_setup) { lib3()->ui->admin_message(implode('<br>', $msg), '', '', 'ms-update'); } do_action('ms_model_upgrade_after_update', $settings, $old_version, $new_version, $force); $addons = MS_Factory::load('MS_Model_Addon'); $addons->flush_list(); // This will reload the current page. MS_Plugin::flush_rewrite_rules(); } }
/** * Prepare the HTML fields that can be displayed * * @since 1.0.0 * * @return array */ protected function prepare_fields() { // Prepare the return value. $nav = array(); $pages = array(); MS_Model_Pages::create_missing_pages(); $page_types = MS_Model_Pages::get_page_types(); $page_types_menu = array('memberships', 'register', 'account'); $page_types_rest = array_diff($page_types, $page_types_menu); // Prepare NAV fields. $menu_action = MS_Controller_Pages::AJAX_ACTION_TOGGLE_MENU; $menu_nonce = wp_create_nonce($menu_action); foreach ($page_types_menu as $type) { $nav_exists = MS_Model_Pages::has_menu($type); $nav[$type] = array('type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'id' => 'nav_' . $type, 'value' => $nav_exists, 'title' => $page_types[$type], 'ajax_data' => array('action' => $menu_action, 'item' => $type, '_wpnonce' => $menu_nonce)); } $nav['sep'] = array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR); // Prepare PAGES fields. $pages_action = MS_Controller_Pages::AJAX_ACTION_UPDATE_PAGES; $pages_nonce = wp_create_nonce($pages_action); foreach ($page_types as $type => $label) { $page_id = MS_Model_Pages::get_setting($type); $title = sprintf('<strong>%1$s</strong><span class="lbl-details">: %2$s</span>', $label, MS_Model_Pages::get_description($type)); $pages[$type] = array('id' => $type, 'type' => MS_Helper_Html::INPUT_TYPE_WP_PAGES, 'title' => $title, 'value' => $page_id, 'field_options' => array('no_item' => __('- Select a page -', MS_TEXT_DOMAIN)), 'ajax_data' => array('field' => $type, 'action' => $pages_action, '_wpnonce' => $pages_nonce)); } $fields = array('nav' => $nav, 'pages' => $pages); return apply_filters('ms_view_settings_page_setup_prepare_fields', $fields, $this); }
/** * Checks member permissions and protects current page. * * Related Action Hooks: * - template_redirect * * @since 1.0.0 */ public function protect_current_page() { do_action('ms_model_plugin_protect_current_page_before', $this); // Admin user has access to everything if ($this->member->is_normal_admin()) { return; } $access = $this->get_access_info(); if (!$access['has_access']) { MS_Model_Pages::create_missing_pages(); $no_access_page_url = MS_Model_Pages::get_page_url(MS_Model_Pages::MS_PAGE_PROTECTED_CONTENT, false); $current_page_url = MS_Helper_Utility::get_current_url(); // Don't (re-)redirect the protection page. if (!MS_Model_Pages::is_membership_page(null, MS_Model_Pages::MS_PAGE_PROTECTED_CONTENT)) { $no_access_page_url = esc_url_raw(add_query_arg(array('redirect_to' => urlencode($current_page_url)), $no_access_page_url)); $no_access_page_url = apply_filters('ms_model_plugin_protected_content_page', $no_access_page_url); wp_safe_redirect($no_access_page_url); exit; } } do_action('ms_model_plugin_protect_current_page_after', $this); }