WP-Members Membership Plugin - Version 3.4.2

Version Description

  • Applies checkbox CSS in add new user form.
  • Code consolidation in admin options tab file (remove final use of wpmem_use_ssl()).
  • Add wpmem_recaptcha_url filter to allow for changing the URL of the recaptcha script.
  • Only apply pwd reset override on frontend (for login error).
  • Fixes undefined $wpmem->reg_form_showing.
  • Fixes a bug in the password change shortcode that causes a "too few arguments" error.
  • Changes wpmem_is_user_current() to wpmem_user_is_current() for backwards compatibility with the plugin's premium PayPal extension.
  • Added the action being done as a parameter passed to the wpmem_get_action action hook.
  • Added support for arrays, urls, and classes to wpmem_sanitize_field() (alias of rktgk_sanitize_field()). This is in addition to the sanitization already supported.
  • apply_custom_product_message() now runs do_shortcode() to natively support shortcodes in custom membership product messages.
  • Fixed an issue that did not display the custom product message if the user was not logged in.
  • Improved custom product message for non-logged in state (same function is used by both logged in and logged out processes, so cleaned up to handle both states the same).
  • Bug fix in password reset that potentially truncates the reset link.
  • Bug fix in admin notification email for HTML formatted email (wpautop() was not being applied to email content).
  • Bug fix in wpmem_is_reg_type() that returned invalid object var.
  • Added email arg for default linebreak.
  • Added user ID to email filters.
  • Added id, class, and wrapper attributes to [wpmem_logged_in] shortcode (wrapper defaults to "div" but can be changed to "span" or "p" or something else).
  • Added user confirmed field to default export fields (if confirmation link setting is enabled).
  • Added wpmem_set_user_membership(), wpmem_remove_user_membership(), and wpmem_get_user_memberships() API functions.
  • Introduces new installer/onboarding for both new installs and upgrades.
Download this release

Release Info

Developer cbutlerjr
Plugin Icon 128x128 WP-Members Membership Plugin
Version 3.4.2
Comparing to
See all releases

Code changes from version 3.4.1.2 to 3.4.2

includes/admin/class-wp-members-admin-api.php CHANGED
@@ -47,12 +47,26 @@ class WP_Members_Admin_API {
47
  * @since 3.1.0
48
  */
49
  function __construct() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  // Load dependencies.
52
  $this->load_dependencies();
53
 
54
  // Load admin hooks.
55
- $this->load_hooks();
56
 
57
  // The following is only needed if we are on the WP-Members settings screen.
58
  $is_wpmem_admin = wpmem_get( 'page', false, 'get' );
@@ -62,7 +76,6 @@ class WP_Members_Admin_API {
62
  $dialogs = $this->default_dialogs(); // Load default dialogs.
63
  }
64
 
65
- global $wpmem;
66
  $wpmem->membership->admin = new WP_Members_Products_Admin();
67
  }
68
 
@@ -111,7 +124,7 @@ class WP_Members_Admin_API {
111
  *
112
  * @global object $wpmem
113
  */
114
- function load_hooks() {
115
 
116
  global $wpmem;
117
 
@@ -184,6 +197,14 @@ class WP_Members_Admin_API {
184
  if ( current_user_can( 'manage_options' ) ) {
185
  add_action( 'admin_notices', array( $this, 'do_admin_notices' ) );
186
  }
 
 
 
 
 
 
 
 
187
  } // End of load_hooks()
188
 
189
  /**
@@ -638,6 +659,42 @@ class WP_Members_Admin_API {
638
  return get_post_types( array( 'public' => true, '_builtin' => false ), 'names', 'and' );
639
  }
640
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  } // End of WP_Members_Admin_API class.
642
 
643
  // End of file.
47
  * @since 3.1.0
48
  */
49
  function __construct() {
50
+
51
+ global $wpmem;
52
+
53
+ $install_state = get_option( 'wpmembers_install_state' );
54
+
55
+ if ( 'new_install' == $install_state ) {
56
+ require_once( $wpmem->path . 'includes/install.php' );
57
+ wpmem_onboarding_new_install( $wpmem->path, $wpmem->version );
58
+ }
59
+
60
+ if ( 'update_pending' == $install_state ) {
61
+ require_once( $wpmem->path . 'includes/install.php' );
62
+ wpmem_onboarding_pending_update( $wpmem->path, $wpmem->version );
63
+ }
64
 
65
  // Load dependencies.
66
  $this->load_dependencies();
67
 
68
  // Load admin hooks.
69
+ $this->load_hooks( $install_state );
70
 
71
  // The following is only needed if we are on the WP-Members settings screen.
72
  $is_wpmem_admin = wpmem_get( 'page', false, 'get' );
76
  $dialogs = $this->default_dialogs(); // Load default dialogs.
77
  }
78
 
 
79
  $wpmem->membership->admin = new WP_Members_Products_Admin();
80
  }
81
 
124
  *
125
  * @global object $wpmem
126
  */
127
+ function load_hooks( $install_state ) {
128
 
129
  global $wpmem;
130
 
197
  if ( current_user_can( 'manage_options' ) ) {
198
  add_action( 'admin_notices', array( $this, 'do_admin_notices' ) );
199
  }
200
+
201
+ if ( 'new_install' == $install_state && 'wp-members-onboarding' != wpmem_get( 'page', false, 'get' ) ) {
202
+ add_action( 'admin_notices', array( $this, 'new_install_notice' ) );
203
+ }
204
+
205
+ if ( 'update_pending' == $install_state && 'wp-members-onboarding' != wpmem_get( 'page', false, 'get' ) ) {
206
+ add_action( 'admin_notices', array( $this, 'upgrade_notice' ) );
207
+ }
208
  } // End of load_hooks()
209
 
210
  /**
659
  return get_post_types( array( 'public' => true, '_builtin' => false ), 'names', 'and' );
660
  }
661
 
662
+ function new_install_notice() {
663
+ echo '<div class="notice notice-info">
664
+ <form action="index.php?page=wp-members-onboarding" method="post">
665
+ <p style="font-weight:bold;">' . __( 'Thank you for installing WP-Members, the original WordPress membership plugin.', 'wp-members' ) . '</p>
666
+ <h3>' . __( 'Never miss an important update!', 'wp-members' ) . '</h3>
667
+ <p><input type="checkbox" name="optin" value="1" checked />' . __( 'Opt-in to our security and feature updates notifications and non-sensitive diagnostic tracking.', 'wp-members' ) . '</p>
668
+ <p class="description">
669
+ ' . __( 'This is only so we know how the plugin is being used so we can make it better and more secure.', 'wp-members' ) . '<br />
670
+ ' . __( 'We do not track any personal information, and no data is ever shared with third parties!', 'wp-members' ) . '
671
+ </p>
672
+ <input type="hidden" name="page" value="wp-members-onboarding" />
673
+ <input type="hidden" name="step" value="finalize">
674
+ <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="' . __( 'Complete plugin setup', 'wp-members' ) . ' &raquo;"></p>
675
+ </form>
676
+ </div>';
677
+ }
678
+
679
+ function upgrade_notice() {
680
+ $onboarding_release_notes = "https://rocketgeek.com/release-notes/wp-members-3-4-2/";
681
+ echo '<div class="notice notice-info">
682
+ <form action="index.php?page=wp-members-onboarding" method="post">
683
+ <h3>' . __( 'Thank you for updating WP-Members, the original WordPress membership plugin.', 'wp-members' ) . '</h3>
684
+ <p class="description"><a href="' . $onboarding_release_notes . '" target="_blank">' . __( 'Read the release notes', 'wp-members' ) . '</a></p>
685
+ <h3>' . __( 'Never miss an important update!', 'wp-members' ) . '</h3>
686
+ <p><input type="checkbox" name="optin" value="1" checked />' . __( 'Opt-in to our security and feature updates notifications and non-sensitive diagnostics.', 'wp-members' ) . '</p>
687
+ <p class="description">
688
+ ' . __( 'This is only so we know how the plugin is being used so we can make it better and more secure.', 'wp-members' ) . '<br />
689
+ ' . __( 'We do not track any personal information, and no data is ever shared with third parties!', 'wp-members' ) . '
690
+ </p>
691
+ <input type="hidden" name="page" value="wp-members-onboarding" />
692
+ <input type="hidden" name="step" value="finalize">
693
+ <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="' . __( 'Complete the update', 'wp-members' ) . ' &raquo;"></p>
694
+ </form>
695
+ </div>';
696
+ }
697
+
698
  } // End of WP_Members_Admin_API class.
699
 
700
  // End of file.
includes/admin/class-wp-members-admin-users.php CHANGED
@@ -194,7 +194,7 @@ class WP_Members_Admin_Users {
194
  $user_id = filter_var( $_REQUEST['user'], FILTER_VALIDATE_INT );
195
 
196
  // Check to see if the user is already activated, if not, activate.
197
- if ( $users == get_current_user_id() ) {
198
  $msg = urlencode( sprintf( esc_html__( 'You cannot confirm or unconfirm yourself', 'wp-members' ) ) );
199
 
200
  } elseif ( 'confirm-single' == $action && false === wpmem_is_user_confirmed( $user_id ) ) {
194
  $user_id = filter_var( $_REQUEST['user'], FILTER_VALIDATE_INT );
195
 
196
  // Check to see if the user is already activated, if not, activate.
197
+ if ( $user_id == get_current_user_id() ) {
198
  $msg = urlencode( sprintf( esc_html__( 'You cannot confirm or unconfirm yourself', 'wp-members' ) ) );
199
 
200
  } elseif ( 'confirm-single' == $action && false === wpmem_is_user_confirmed( $user_id ) ) {
includes/admin/class-wp-members-user-export.php CHANGED
@@ -53,8 +53,8 @@ class WP_Members_User_Export {
53
  * @type string $role The user's role (or roles, if multiple).
54
  * }
55
  * @type array $exclude_fields @deprecated 3.4.0
56
- * @type boolean $entity_decode
57
- * @type string $date_format
58
  * }
59
  * @param array $users Array of user IDs to export.
60
  * @param string $tag
@@ -285,6 +285,9 @@ class WP_Members_User_Export {
285
  if ( wpmem_is_enabled( 'mod_reg' ) ) {
286
  $export_fields['active'] = __( 'Activated?', 'wp-members' );
287
  }
 
 
 
288
  if ( defined( 'WPMEM_EXP_MODULE' ) && wpmem_is_enabled( 'use_exp' ) ) {
289
  $export_fields['exp_type'] = __( 'Subscription', 'wp-members' );
290
  $export_fields['expires'] = __( 'Expires', 'wp-members' );
53
  * @type string $role The user's role (or roles, if multiple).
54
  * }
55
  * @type array $exclude_fields @deprecated 3.4.0
56
+ * @type boolean $entity_decode Whether HTML entities should be decoded (default: false)
57
+ * @type string $date_format A PHP readable date format (default: Y-m-d which results in YYYY-MM-DD)
58
  * }
59
  * @param array $users Array of user IDs to export.
60
  * @param string $tag
285
  if ( wpmem_is_enabled( 'mod_reg' ) ) {
286
  $export_fields['active'] = __( 'Activated?', 'wp-members' );
287
  }
288
+ if ( wpmem_is_enabled( 'act_link' ) ) {
289
+ $export_fields['_wpmem_user_confirmed'] = __( 'Confirmed?', 'wp-members' );
290
+ }
291
  if ( defined( 'WPMEM_EXP_MODULE' ) && wpmem_is_enabled( 'use_exp' ) ) {
292
  $export_fields['exp_type'] = __( 'Subscription', 'wp-members' );
293
  $export_fields['expires'] = __( 'Expires', 'wp-members' );
includes/admin/class-wp-members-user-search.php CHANGED
@@ -21,15 +21,6 @@ if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  class WP_Members_Admin_User_Search {
23
 
24
- /**
25
- * Container for tabs.
26
- *
27
- * @since 3.1.9
28
- * @access public
29
- * @var array
30
- */
31
- public $tabs = array();
32
-
33
  /**
34
  * Container for user search meta keys.
35
  *
21
 
22
  class WP_Members_Admin_User_Search {
23
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * Container for user search meta keys.
26
  *
includes/admin/partials/onboarding_finalize.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $utms = array(
3
+ 'utm_source' => get_site_url(),
4
+ 'utm_medium' => 'wp-members-core-plugin',
5
+ 'utm_campaign' => 'plugin-install',
6
+ );
7
+
8
+ $action_complete = ( 'update_pending' == $install_state ) ? __( 'Plugin update complete', 'wp-members' ) : __( 'Plugin installation complete', 'wp-members' );
9
+ ?>
10
+ <div id="wpmem_onboarding">
11
+ <div class="wrapper">
12
+ <h1><?php echo $onboarding_title; ?></h1>
13
+ <p class="section_lead"><?php echo $action_complete; ?></p>
14
+
15
+ <?php if ( 'update_pending' == $install_state ) { ?>
16
+ <ul>
17
+ <li>&raquo; <a href="<?php echo $onboarding_release_notes . "?" . http_build_query( $utms ); ?>" target="_blank"><?php printf( __( 'WP-Members version %s release notes', 'wp-members' ), $onboarding_version ); ?></a></li>
18
+ <li>&raquo; <a href="https://rocketgeek.com/plugins/wp-members/docs/?<?php echo http_build_query( $utms ); ?>" target="_blank"><?php _e( 'WP-Members documentation', 'wp-members' ); ?></a></li>
19
+ </ul>
20
+ <?php } else { ?>
21
+ <p>WP-Members installs some basic defaults to get you started. Be sure to review <a href="<?php echo admin_url(); ?>options-general.php?page=wpmem-settings">the plugin's default setup here</a>.
22
+ There are links to related documentation in the plugin settings. There are also some helpful links below.</p>
23
+ <ul>
24
+ <li>&raquo; <a href="<?php echo $onboarding_release_notes . "?" . http_build_query( $utms ); ?>" target="_blank"><?php printf( __( 'WP-Members version %s release notes', 'wp-members' ), $onboarding_version ); ?></a></li>
25
+ <li>&raquo; <a href="https://rocketgeek.com/plugins/wp-members/docs/?<?php echo http_build_query( $utms ); ?>" target="_blank"><?php _e( 'WP-Members documentation', 'wp-members' ); ?></a></li>
26
+ </ul>
27
+ <?php } ?>
28
+ <h2><?php _e( 'Want more features?', 'wp-members' ); ?></h2>
29
+ <p>There are <a href="https://rocketgeek.com/store/?<?php echo http_build_query( $utms ); ?>" target="_blank">premium plugin add-ons</a> available as well as a <a href="https://rocketgeek.com/plugins/wp-members/support-options/?<?php echo http_build_query( $utms ); ?>" target="_blank">discounted bundle</a>.</p>
30
+ <h2>Need more help?</h2>
31
+ <p>If you need additional assistance, consider a <a href="https://rocketgeek.com/plugins/wp-members/support-options/?<?php echo http_build_query( $utms ); ?>" target="_blank">premium support subscription</a>.</p>
32
+ <p>&nbsp;</p>
33
+ <ul>
34
+ <li>&raquo; <a href="<?php echo admin_url() . 'options-general.php?page=wpmem-settings'; ?>"><?php _e( 'Go to WP-Members settings', 'wp-members' ); ?></a></li>
35
+ <li>&raquo; <a href="<?php echo admin_url() . 'plugins.php'; ?>"><?php _e( 'Go to Plugins page', 'wp-members' ); ?></a></li>
36
+ <li>&raquo; <a href="<?php echo admin_url() . 'update-core.php'; ?>"><?php _e( 'Go to WordPress Updates page', 'wp-members' ); ?></a></li>
37
+ </ul>
38
+ </div>
39
+ </div>
includes/admin/tabs/class-wp-members-admin-tab-fields.php CHANGED
@@ -233,8 +233,8 @@ class WP_Members_Admin_Tab_Fields {
233
  </li>
234
  <!--<div id="wpmem_allowhtml">
235
  <li>
236
- <label><?php _e( 'Allow HTML?', 'wp-members' ); ?></label>
237
- <input type="checkbox" name="add_html" value="y" <?php echo ( $mode == 'edit' ) ? checked( true, $field['html'] ) : false; ?> />
238
  </li>
239
  </div>-->
240
  <?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'password', 'email', 'url', 'number', 'date', 'textarea' ) ) ) ) ) { ?>
233
  </li>
234
  <!--<div id="wpmem_allowhtml">
235
  <li>
236
+ <label><?php //_e( 'Allow HTML?', 'wp-members' ); ?></label>
237
+ <input type="checkbox" name="add_html" value="y" <?php //echo ( $mode == 'edit' ) ? checked( true, $field['html'] ) : false; ?> />
238
  </li>
239
  </div>-->
240
  <?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'password', 'email', 'url', 'number', 'date', 'textarea' ) ) ) ) ) { ?>
includes/admin/tabs/class-wp-members-admin-tab-options.php CHANGED
@@ -160,8 +160,8 @@ class WP_Members_Admin_Tab_Options {
160
  <?php
161
  if ( WPMEM_EXP_MODULE == true ) {
162
  $rows = array(
163
- array(__('Time-based expiration','wp-members'),'wpmem_settings_time_exp',__('Allows for access to expire','wp-members'),'use_exp'),
164
- array(__('Trial period','wp-members'),'wpmem_settings_trial',__('Allows for a trial period','wp-members'),'use_trial'),
165
  ); ?>
166
  <h3><?php _e( 'Subscription Settings', 'wp-members' ); ?></h3>
167
  <ul><?php
@@ -182,6 +182,7 @@ class WP_Members_Admin_Tab_Options {
182
  array(__('Legacy Password Reset', 'wp-members'),'wpmem_settings_pwd_link',sprintf(__('Use legacy password reset. %s(Requires additional configuration)%s','wp-members'),$reset_link_start,$reset_link_end),'pwd_link'),
183
  //array(__('Enable WP Login Error', 'wp-members' ),'wpmem_settings_login_error',__('Use WP login error object instead of WP-Members default login error','wp-members'),'login_error'),
184
  array(__('Legacy Login Error', 'wp-members' ),'wpmem_settings_login_error',__('Use legacy WP-Members login error instead of WP error object.','wp-members'),'login_error'),
 
185
  );
186
  if ( wpmem_is_woo_active() ) {
187
  $rows[] = array(__('WooCommerce My Account', 'wp-members' ),'wpmem_settings_add_my_account_fields',__('Add WP-Members fields to WooCommerce My Account registration','wp-members'),'add_my_account_fields');
@@ -191,7 +192,7 @@ class WP_Members_Admin_Tab_Options {
191
  foreach ( $rows as $key => $row ) { ?>
192
  <li>
193
  <label><?php echo $row[0]; ?></label>
194
- <?php $checkbox_value = ( 2 == $key || 3 == $key ) ? $wpmem->woo[ $row[3] ] : $wpmem->{$row[3]}; ?>
195
  <?php if ( 1 == $key || 0 == $key ) {
196
  echo wpmem_form_field( $row[1], 'checkbox', '0', $checkbox_value ); ?>&nbsp;&nbsp;
197
  <?php } else {
@@ -598,6 +599,14 @@ class WP_Members_Admin_Tab_Options {
598
  }
599
  $wpmem->{$key} = $val;
600
  }
 
 
 
 
 
 
 
 
601
  }
602
 
603
  /**
160
  <?php
161
  if ( WPMEM_EXP_MODULE == true ) {
162
  $rows = array(
163
+ array(__('Enable PayPal','wp-members'),'wpmem_settings_time_exp',__('Requires payment through PayPal following registration','wp-members'),'use_exp'),
164
+ array(__('Trial period','wp-members'),'wpmem_settings_trial',__('Allows for a trial period before PayPal payment is required','wp-members'),'use_trial'),
165
  ); ?>
166
  <h3><?php _e( 'Subscription Settings', 'wp-members' ); ?></h3>
167
  <ul><?php
182
  array(__('Legacy Password Reset', 'wp-members'),'wpmem_settings_pwd_link',sprintf(__('Use legacy password reset. %s(Requires additional configuration)%s','wp-members'),$reset_link_start,$reset_link_end),'pwd_link'),
183
  //array(__('Enable WP Login Error', 'wp-members' ),'wpmem_settings_login_error',__('Use WP login error object instead of WP-Members default login error','wp-members'),'login_error'),
184
  array(__('Legacy Login Error', 'wp-members' ),'wpmem_settings_login_error',__('Use legacy WP-Members login error instead of WP error object.','wp-members'),'login_error'),
185
+ array(__('Notifications & Diagnostics', 'wp-members' ),'wpmem_settings_optin',__('Opt in to security and updates notifications and non-sensitive diagnostics tracking', 'wp-members'),'optin'),
186
  );
187
  if ( wpmem_is_woo_active() ) {
188
  $rows[] = array(__('WooCommerce My Account', 'wp-members' ),'wpmem_settings_add_my_account_fields',__('Add WP-Members fields to WooCommerce My Account registration','wp-members'),'add_my_account_fields');
192
  foreach ( $rows as $key => $row ) { ?>
193
  <li>
194
  <label><?php echo $row[0]; ?></label>
195
+ <?php $checkbox_value = ( 3 == $key || 4 == $key ) ? $wpmem->woo[ $row[3] ] : $wpmem->{$row[3]}; ?>
196
  <?php if ( 1 == $key || 0 == $key ) {
197
  echo wpmem_form_field( $row[1], 'checkbox', '0', $checkbox_value ); ?>&nbsp;&nbsp;
198
  <?php } else {
599
  }
600
  $wpmem->{$key} = $val;
601
  }
602
+
603
+ if ( isset( $_POST['wpmem_settings_optin'] ) && 0 == $wpmem->optin ) {
604
+ update_option( 'wpmembers_optin', 1 );
605
+ $wpmem->optin = 1;
606
+ } elseif ( ! isset( $_POST['wpmem_settings_optin'] ) && 1 == $wpmem->optin ) {
607
+ update_option( 'wpmembers_optin', 0 );
608
+ $wpmem->optin = 0;
609
+ }
610
  }
611
 
612
  /**
includes/api/api-forms.php CHANGED
@@ -83,12 +83,14 @@ endif;
83
  * Use the WP login form.
84
  *
85
  * @since 3.3.2
 
86
  *
87
  * @global stdClass $wpmem
88
  * @param array $args
89
  */
90
  function wpmem_wp_login_form( $args ) {
91
  global $wpmem;
 
92
  return $wpmem->forms->wp_login_form( $args );
93
  }
94
 
@@ -296,11 +298,13 @@ function wpmem_fields( $tag = '', $form = 'default' ) {
296
  *
297
  * @since 3.1.7
298
  * @since 3.3.2 Change object var and return.
 
299
  *
300
  * @param array $wpmem->fields
301
- * @param string $tag (optional)
 
302
  */
303
- $wpmem->fields = apply_filters( 'wpmem_fields', $wpmem->fields, $tag );
304
 
305
  return $wpmem->fields;
306
  }
@@ -347,12 +351,13 @@ function wpmem_sanitize_array( $data, $type = false ) {
347
  * A multi use sanitization function.
348
  *
349
  * @since 3.3.0
 
350
  *
351
  * @global object $wpmem
352
  *
353
- * @param string $data
354
- * @param string $type (multiselect|multicheckbox|textarea|email|file|image|int|integer|number)
355
- * @return string $sanitized_data
356
  */
357
  function wpmem_sanitize_field( $data, $type = 'text' ) {
358
  return rktgk_sanitize_field( $data, $type );
@@ -593,18 +598,37 @@ function wpmem_is_reg_form_showing() {
593
  return ( isset( $wpmem->reg_form_showing ) && true == $wpmem->reg_form_showing ) ? true : false;
594
  }
595
 
596
- function wpmem_field_display_value( $field, $type, $value, $echo = false ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
  $fields = wpmem_fields();
 
 
 
 
598
  /**
599
  * Filter the value.
600
  *
601
  * @since 3.4.0
602
  *
603
  * @param string $display_value
604
- * @param string $field
605
  * @param string $type
606
  */
607
- $display_value = apply_filters( 'wpmem_' . $type . '_field_display', $fields[ $field ]['options'][ $value ], $field, $type );
608
  if ( $echo ) {
609
  echo $display_value;
610
  } else {
@@ -612,23 +636,10 @@ function wpmem_field_display_value( $field, $type, $value, $echo = false ) {
612
  }
613
  }
614
 
615
- function wpmem_checkbox_field_display( $field, $value, $echo = false ) {
616
- wpmem_field_display_value( $field, 'checkbox', $value, $echo );
617
  }
618
 
619
- function wpmem_select_field_display( $field, $value, $echo = false ) {
620
- wpmem_field_display_value( $field, 'select', $value, $echo );
621
- }
622
-
623
- function wpmem_get_user_meta_select( $user_id, $field ) {
624
- $value = wpmem_get_user_meta( $user_id, $field );
625
- return wpmem_select_field_display( $field, $value );
626
- }
627
-
628
- function wpmem_get_user_meta_radio( $user_id, $field ) {
629
- return wpmem_get_user_meta_select( $user_id, $field );
630
- }
631
-
632
- function wpmem_get_user_meta_multi( $user_id, $field ) {
633
-
634
  }
83
  * Use the WP login form.
84
  *
85
  * @since 3.3.2
86
+ * @since 3.4.2 echo set to false by default.
87
  *
88
  * @global stdClass $wpmem
89
  * @param array $args
90
  */
91
  function wpmem_wp_login_form( $args ) {
92
  global $wpmem;
93
+ $args['echo'] = ( ! isset( $args['echo'] ) ) ? false : $args['echo'];
94
  return $wpmem->forms->wp_login_form( $args );
95
  }
96
 
298
  *
299
  * @since 3.1.7
300
  * @since 3.3.2 Change object var and return.
301
+ * @since 3.4.2 Added $form parameter.
302
  *
303
  * @param array $wpmem->fields
304
+ * @param string $tag (optional)
305
+ * @param string $form (optional)
306
  */
307
+ $wpmem->fields = apply_filters( 'wpmem_fields', $wpmem->fields, $tag, $form );
308
 
309
  return $wpmem->fields;
310
  }
351
  * A multi use sanitization function.
352
  *
353
  * @since 3.3.0
354
+ * @since 3.4.2 Added text, url, array, class as accepted $type
355
  *
356
  * @global object $wpmem
357
  *
358
+ * @param string $data
359
+ * @param string $type (text|array|multiselect|multicheckbox|textarea|email|file|image|int|integer|number|url|class) Default:text
360
+ * @return string $sanitized_data
361
  */
362
  function wpmem_sanitize_field( $data, $type = 'text' ) {
363
  return rktgk_sanitize_field( $data, $type );
598
  return ( isset( $wpmem->reg_form_showing ) && true == $wpmem->reg_form_showing ) ? true : false;
599
  }
600
 
601
+ /**
602
+ * Returns the display value of certain field types.
603
+ *
604
+ * Some WP-Members field types may have a different "saved" value and
605
+ * "displayed" value. This function provides a simple way to get the displayed
606
+ * value for a field based on the saved value.
607
+ *
608
+ * @since 3.4.0
609
+ * @since 3.4.2 Cleanup, completed support for all field types.
610
+ *
611
+ * @param string $field_meta The meta key for the requested field.
612
+ * @param string $value The value to convert (empty for checkbox).
613
+ * @param boolean $echo Whether to echo or return the value (default: false).
614
+ * @return string
615
+ */
616
+ function wpmem_field_display_value( $field_meta, $value = '', $echo = false ) {
617
  $fields = wpmem_fields();
618
+ $type = $fields[ $field_meta ]['type'];
619
+
620
+ $display_value = ( 'checkbox' == $type ) ? $fields[ $field_meta ]['label'] : $fields[ $field_meta ]['options'][ $value ];
621
+
622
  /**
623
  * Filter the value.
624
  *
625
  * @since 3.4.0
626
  *
627
  * @param string $display_value
628
+ * @param string $field_meta
629
  * @param string $type
630
  */
631
+ $display_value = apply_filters( 'wpmem_' . $type . '_field_display', $display_value, $field_meta, $type );
632
  if ( $echo ) {
633
  echo $display_value;
634
  } else {
636
  }
637
  }
638
 
639
+ function wpmem_checkbox_field_display( $field_meta, $echo = false ) {
640
+ return wpmem_field_display_value( $field_meta, '', $echo );
641
  }
642
 
643
+ function wpmem_select_field_display( $field_meta, $value, $echo = false ) {
644
+ return wpmem_field_display_value( $field_meta, $value, $echo );
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  }
includes/api/api-users.php CHANGED
@@ -106,6 +106,75 @@ function wpmem_get_user_meta( $user_id, $meta_key ) {
106
  return get_user_meta( $user_id, $meta_key, true );
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  /**
110
  * Checks if a user has a given meta value.
111
  *
@@ -239,9 +308,9 @@ function wpmem_user_has_access( $product, $user_id = false ) {
239
  *
240
  * Must be named _user_is_current() as _is_user_current() exists in PayPal extension.
241
  *
242
- * @since 3.3.9
243
  *
244
- * @param mixed $product
245
  * @param integer $user_id
246
  * @return boolean
247
  */
@@ -252,11 +321,39 @@ function wpmem_user_is_current( $product, $user_id = false ) {
252
  return ( $wpmem->user->is_current( $memberships[ $product ] ) ) ? true : false;
253
  }
254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  /**
256
  * Sets product access for a user.
257
  *
258
  * @since 3.2.3
259
  * @since 3.2.6 Added $date to set a specific expiration date.
 
260
  *
261
  * @global object $wpmem
262
  * @param string $product The meta key of the product.
@@ -273,6 +370,7 @@ function wpmem_set_user_product( $product, $user_id = false, $date = false ) {
273
  * Removes product access for a user.
274
  *
275
  * @since 3.2.3
 
276
  *
277
  * @global object $wpmem
278
  * @param string $product
@@ -288,6 +386,7 @@ function wpmem_remove_user_product( $product, $user_id = false ) {
288
  * Gets memberships a user has.
289
  *
290
  * @since 3.3.0
 
291
  *
292
  * @global stdClass $wpmem
293
  * @param int $user_id
@@ -298,6 +397,24 @@ function wpmem_get_user_products( $user_id = false ) {
298
  return ( $user_id ) ? $wpmem->user->get_user_products( $user_id ) : $wpmem->user->access;
299
  }
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  /**
302
  * Sets a user as logged in.
303
  *
@@ -623,7 +740,7 @@ function wpmem_user_register( $tag ) {
623
  }
624
 
625
  // Inserts to wp_users table.
626
- $user = wp_insert_user( $new_user_fields );
627
 
628
  /**
629
  * Fires after registration is complete.
@@ -635,8 +752,9 @@ function wpmem_user_register( $tag ) {
635
  * @since 3.3.8 Added $user parameter.
636
  *
637
  * @param array $wpmem->user->post_data The user's submitted registration data.
 
638
  */
639
- do_action( 'wpmem_register_redirect', $wpmem->user->post_data, $user );
640
 
641
  // successful registration message
642
  return "success";
@@ -758,8 +876,9 @@ function wpmem_user_register( $tag ) {
758
  * @since 2.7.2
759
  *
760
  * @param array $wpmem->user->post_data The user's submitted registration data.
 
761
  */
762
- do_action( 'wpmem_post_update_data', $wpmem->user->post_data );
763
 
764
  return "editsuccess"; exit();
765
  break;
@@ -801,8 +920,32 @@ function wpmem_get_user_ip() {
801
  *
802
  * @global object $wpmem
803
  *
804
- * @param array $args
805
- * @param array $users
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
806
  */
807
  function wpmem_export_users( $args = array(), $users = array() ) {
808
  global $wpmem;
106
  return get_user_meta( $user_id, $meta_key, true );
107
  }
108
 
109
+ /**
110
+ * Get a user meta checkbox label as value if checked.
111
+ *
112
+ * @since 3.4.2
113
+ *
114
+ * @param int $user_id
115
+ * @param string $meta_key
116
+ * @return string $result
117
+ */
118
+ function wpmem_get_user_meta_checkbox( $user_id, $meta_key ) {
119
+ $value = wpmem_get_user_meta( $user_id, $meta_key );
120
+ return wpmem_checkbox_field_display( $value );
121
+ }
122
+
123
+ /**
124
+ * Get a user meta select (dropdown) value.
125
+ *
126
+ * @since 3.4.2
127
+ *
128
+ * @param int $user_id
129
+ * @param string $meta_key
130
+ * @return string $result
131
+ */
132
+ function wpmem_get_user_meta_select( $user_id, $meta_key ) {
133
+ $value = wpmem_get_user_meta( $user_id, $meta_key );
134
+ return wpmem_select_field_display( $meta_key, $value );
135
+ }
136
+
137
+ /**
138
+ * Get a user meta radio value.
139
+ * Alias of wpmem_get_user_meta_select() for radio field type.
140
+ *
141
+ * @since 3.4.2
142
+ *
143
+ * @param int $user_id
144
+ * @param string $meta_key
145
+ * @return string $result
146
+ */
147
+ function wpmem_get_user_meta_radio( $user_id, $meta_key ) {
148
+ return wpmem_get_user_meta_select( $user_id, $meta_key );
149
+ }
150
+
151
+ /**
152
+ * Returns the meta value for a requested mutli-checkbox or multi-select
153
+ * field for a requested user ID.
154
+ *
155
+ * @since 3.4.2
156
+ *
157
+ * @param int $user_id
158
+ * @param string $field_meta
159
+ * @param string $return_type (string|array default:string)
160
+ * @return string
161
+ */
162
+ function wpmem_get_user_meta_multi( $user_id, $field_meta, $return_type = "string" ) {
163
+ $fields = wpmem_fields();
164
+ $value = wpmem_get_user_meta( $user_id, $field_meta );
165
+ $array = ( '' != $value && false != $value ) ? explode( $fields[ $field_meta ]['delimiter'], $value ) : array();
166
+ if ( ! empty( $array ) && count( $array ) > 1 ) {
167
+ foreach ( $array as $val ) {
168
+ $display_values[] = wpmem_field_display_value( $field_meta, $val );
169
+ }
170
+ $return_value = ( "array" == $return_type ) ? $display_values : implode( ", ", $display_values );
171
+ } else {
172
+ $display_value = wpmem_field_display_value( $field_meta, $value );
173
+ $return_value = ( "array" == $return_type ) ? array( $display_value ) : $display_value;
174
+ }
175
+ return $return_value;
176
+ }
177
+
178
  /**
179
  * Checks if a user has a given meta value.
180
  *
308
  *
309
  * Must be named _user_is_current() as _is_user_current() exists in PayPal extension.
310
  *
311
+ * @since 3.4.0
312
  *
313
+ * @param string $product
314
  * @param integer $user_id
315
  * @return boolean
316
  */
321
  return ( $wpmem->user->is_current( $memberships[ $product ] ) ) ? true : false;
322
  }
323
 
324
+ /**
325
+ * An alias for wpmem_set_user_product().
326
+ *
327
+ * @since 3.4.2
328
+ */
329
+ function wpmem_set_user_membership( $membership, $user_id = false, $date = false ) {
330
+ return wpmem_set_user_product( $membership, $user_id, $date );
331
+ }
332
+
333
+ /**
334
+ * An alias for wpmem_remove_user_product().
335
+ *
336
+ * @since 3.4.2
337
+ */
338
+ function wpmem_remove_user_membership( $membership, $user_id = false ) {
339
+ return wpmem_remove_user_product( $membership, $user_id );
340
+ }
341
+
342
+ /**
343
+ * An alias for wpmem_get_user_products().
344
+ *
345
+ * @since 3.4.2
346
+ */
347
+ function wpmem_get_user_memberships( $user_id = false ) {
348
+ return wpmem_get_user_products( $user_id );
349
+ }
350
+
351
  /**
352
  * Sets product access for a user.
353
  *
354
  * @since 3.2.3
355
  * @since 3.2.6 Added $date to set a specific expiration date.
356
+ * @since 3.4.2 Use wpmem_set_user_membership() instead.
357
  *
358
  * @global object $wpmem
359
  * @param string $product The meta key of the product.
370
  * Removes product access for a user.
371
  *
372
  * @since 3.2.3
373
+ * @since 3.4.2 Use wpmem_remove_user_membership() instead.
374
  *
375
  * @global object $wpmem
376
  * @param string $product
386
  * Gets memberships a user has.
387
  *
388
  * @since 3.3.0
389
+ * @since 3.4.2 Use wpmem_get_user_memberships() instead.
390
  *
391
  * @global stdClass $wpmem
392
  * @param int $user_id
397
  return ( $user_id ) ? $wpmem->user->get_user_products( $user_id ) : $wpmem->user->access;
398
  }
399
 
400
+ /**
401
+ * Get user expiration date
402
+ *
403
+ * @since 3.4.2
404
+ *
405
+ * @param $product_key The membership slug being requested (optional: defaults to first membership in the array).
406
+ * @param $user_id The user ID (optional: defaults to current user).
407
+ * @param $format The date format to return (optional: defaults to raw epoch timestamp).
408
+ * @return $exp_date The expiration date unformatted (i.e. unix/epoch timestamp) (false if no date or membership does not exist for user).
409
+ */
410
+ function wpmem_get_user_expiration( $product_key = false, $user_id = false, $format = false ) {
411
+ $user_id = ( false === $user_id ) ? get_current_user_id() : $user_id;
412
+ $memberships = wpmem_get_user_memberships( $user_id );
413
+ $product_key = ( false == $product_key ) ? key( $memberships ) : $product_key;
414
+ $exp_date = ( is_numeric( $memberships[ $product_key ] ) ) ? $memberships[ $product_key ] : strtotime( $memberships[ $product_key ] );
415
+ return $exp_date;
416
+ }
417
+
418
  /**
419
  * Sets a user as logged in.
420
  *
740
  }
741
 
742
  // Inserts to wp_users table.
743
+ $user_id = wp_insert_user( $new_user_fields );
744
 
745
  /**
746
  * Fires after registration is complete.
752
  * @since 3.3.8 Added $user parameter.
753
  *
754
  * @param array $wpmem->user->post_data The user's submitted registration data.
755
+ * @param int $user_id
756
  */
757
+ do_action( 'wpmem_register_redirect', $wpmem->user->post_data, $user_id );
758
 
759
  // successful registration message
760
  return "success";
876
  * @since 2.7.2
877
  *
878
  * @param array $wpmem->user->post_data The user's submitted registration data.
879
+ * @param int $user_id
880
  */
881
+ do_action( 'wpmem_post_update_data', $wpmem->user->post_data, $wpmem->user->post_data['ID'] );
882
 
883
  return "editsuccess"; exit();
884
  break;
920
  *
921
  * @global object $wpmem
922
  *
923
+ * @param array $args array {
924
+ * Array of defaults for export.
925
+ *
926
+ * @type string $export The type of export (all|selected)
927
+ * @type string $filename
928
+ * @type array $fields {
929
+ * The array of export fields is keyed as 'meta_key' => 'heading value'.
930
+ * The array can include fields in the Fields tab, plus the following:
931
+ *
932
+ * @type int $ID ID from wp_users
933
+ * @type string $username user_login from wp_users
934
+ * @type string $user_nicename user_nicename
935
+ * @type string $user_url user_url
936
+ * @type string $display_name display_name
937
+ * @type int $active Whether the user is active/deactivated.
938
+ * @type string $exp_type If the PayPal extension is installed pending|subscrption (optional)
939
+ * @type string $expires If the PayPal extension is installed MM/DD/YYYY (optional)
940
+ * @type string $user_registered user_registered
941
+ * @type string $user_ip The IP of the user when they registered.
942
+ * @type string $role The user's role (or roles, if multiple).
943
+ * }
944
+ * @type array $exclude_fields @deprecated 3.4.0
945
+ * @type boolean $entity_decode Whether HTML entities should be decoded (default: false)
946
+ * @type string $date_format A PHP readable date format (default: Y-m-d which results in YYYY-MM-DD)
947
+ * }
948
+ * @param array $users Array of user IDs to export.
949
  */
950
  function wpmem_export_users( $args = array(), $users = array() ) {
951
  global $wpmem;
includes/api/api.php CHANGED
@@ -473,7 +473,7 @@ function wpmem_is_rest() {
473
  */
474
  function wpmem_is_reg_type( $type ) {
475
  global $wpmem;
476
- return $wpmem->reg_type[ 'is_' . $type ];
477
  }
478
 
479
  /**
473
  */
474
  function wpmem_is_reg_type( $type ) {
475
  global $wpmem;
476
+ return $wpmem->user->reg_type[ 'is_' . $type ];
477
  }
478
 
479
  /**
includes/class-wp-members-email.php CHANGED
@@ -162,6 +162,7 @@ class WP_Members_Email {
162
  $this->settings['disable'] = false;
163
  $this->settings['toggle'] = $this->settings['tag']; // Deprecated since 3.2.0, but remains in the array for legacy reasons.
164
  $this->settings['reset_link'] = esc_url_raw( add_query_arg( array( 'a' => 'pwdreset', 'key' => $password, 'id' => $user_id ), wpmem_profile_url() ) );
 
165
 
166
  // Apply filters (if set) for the sending email address.
167
  $default_header = ( $this->from && $this->from_name ) ? 'From: "' . $this->from_name . '" <' . $this->from . '>' : '';
@@ -171,21 +172,25 @@ class WP_Members_Email {
171
  *
172
  * @since 2.7.4
173
  * @since 3.2.0 Changed toggle to tag.
 
174
  *
175
  * @param mixed $default_header The email headers.
176
  * @param string $this->settings['tag'] Tag to determine what email is being generated (newreg|newmod|appmod|repass|admin).
 
177
  */
178
- $this->settings['headers'] = apply_filters( 'wpmem_email_headers', $default_header, $this->settings['tag'] );
179
 
180
  /**
181
  * Filters attachments.
182
  *
183
  * @since 3.4.1
 
184
  *
185
  * @param mixed $attachments Any file attachments as a string or array. (default per wp_mail() documentation is empty array).
186
  * @param string $this->settings['tag'] Tag to determine what email is being generated (newreg|newmod|appmod|repass|admin).
 
187
  */
188
- $this->settings['attachments'] = apply_filters( 'wpmem_email_attachments', array(), $this->settings['tag'] );
189
 
190
  /**
191
  * Filter the email.
@@ -199,6 +204,7 @@ class WP_Members_Email {
199
  * @since 3.1.0 Added footer content to the array.
200
  * @since 3.2.0 Changed wpmem_msurl key to wpmem_profile.
201
  * @since 3.2.0 Change toggle to tag.
 
202
  *
203
  * @param array $this->settings {
204
  * An array containing email body, subject, user id, and additional settings.
@@ -220,6 +226,7 @@ class WP_Members_Email {
220
  * @type bool disable
221
  * @type mixed headers
222
  * @type string toggle Deprecated since 3.2.0
 
223
  * }
224
  * @param array $wpmem_fields An array of the WP-Members fields.
225
  * @param array $field_data An array of the posted registration data.
@@ -236,6 +243,7 @@ class WP_Members_Email {
236
  * @deprecated 3.2.0 Use wpmem_email_filter instead.
237
  *
238
  * @param string $this->settings['body'] The body content of the new registration email.
 
239
  */
240
  $this->settings['body'] = apply_filters( 'wpmem_email_' . $this->settings['tag'], $this->settings['body'] );
241
 
@@ -273,11 +281,13 @@ class WP_Members_Email {
273
  * Filter available email shortcodes.
274
  *
275
  * @since 3.1.0
 
276
  *
277
  * @param array $shortcodes
278
  * @param string $tag
 
279
  */
280
- $shortcodes = apply_filters( 'wpmem_email_shortcodes', $shortcodes, $this->settings['tag'] );
281
 
282
  $shortcd = array();
283
  $replace = array();
@@ -295,7 +305,7 @@ class WP_Members_Email {
295
  }
296
 
297
  // Append footer if needed.
298
- $this->settings['body'] = ( $this->settings['add_footer'] ) ? $this->settings['body'] . "\r\n" . $foot : $this->settings['body'];
299
 
300
  // Send message.
301
  $this->send( 'user' );
@@ -347,6 +357,11 @@ class WP_Members_Email {
347
  // Get the email stored values.
348
  $this->settings = get_option( 'wpmembers_email_notify' );
349
 
 
 
 
 
 
350
  // Userdata for default shortcodes.
351
  $this->settings['user_id'] = $user_id;
352
  $this->settings['user_login'] = stripslashes( $user->user_login );
@@ -359,8 +374,9 @@ class WP_Members_Email {
359
  $this->settings['exp_date'] = ( defined( 'WPMEM_EXP_MODULE' ) && $wpmem->use_exp == 1 ) ? get_user_meta( $user_id, 'expires', true ) : '';
360
  $this->settings['do_shortcodes'] = true;
361
  $this->settings['add_footer'] = true;
362
- $this->settings['footer'] = get_option( 'wpmembers_email_footer' );
363
  $this->settings['disable'] = false;
 
364
 
365
  // Builds an array of the user data fields.
366
  $field_arr = array();
@@ -388,19 +404,20 @@ class WP_Members_Email {
388
  $default_header = ( $this->from && $this->from_name ) ? 'From: "' . $this->from_name . '" <' . $this->from . '>' : '';
389
 
390
  /** This filter is documented in class-wp-members-email.php */
391
- $this->settings['headers'] = apply_filters( 'wpmem_email_headers', $default_header, 'admin' );
392
 
393
  /** This filter is documented in class-wp-members-email.php */
394
- $this->settings['attachments'] = apply_filters( 'wpmem_email_attachments', array(), 'admin' );
395
 
396
  /**
397
  * Filters the address the admin notification is sent to.
398
  *
399
  * @since 2.7.5
 
400
  *
401
  * @param string The email address of the admin to send to.
402
  */
403
- $this->settings['admin_email'] = apply_filters( 'wpmem_notify_addr', get_option( 'admin_email' ) );
404
 
405
  /**
406
  * Filter the email.
@@ -413,6 +430,7 @@ class WP_Members_Email {
413
  *
414
  * @since 2.9.8
415
  * @since 3.3.9 Added $user param.
 
416
  *
417
  * @param array $this->settings
418
  * An array containing email body, subject, user id, and additional settings.
@@ -435,6 +453,7 @@ class WP_Members_Email {
435
  * @type array $field_arr
436
  * @type string $headers
437
  * @type string $admin_email
 
438
  * }
439
  * @param array $wpmem_fields An array of the WP-Members fields.
440
  * @param array $field_data An array of the posted registration data.
@@ -448,7 +467,7 @@ class WP_Members_Email {
448
  // Split field_arr into field_str.
449
  $field_str = '';
450
  foreach ( $this->settings['field_arr'] as $key => $val ) {
451
- $field_str.= $key . ': ' . $val . "\r\n";
452
  }
453
 
454
  // Get the email footer if needed.
@@ -480,11 +499,12 @@ class WP_Members_Email {
480
  * Filter available email shortcodes.
481
  *
482
  * @since 3.1.0
 
483
  *
484
  * @param array $shortcodes
485
  * @param string $toggle
486
  */
487
- $shortcodes = apply_filters( 'wpmem_email_shortcodes', $shortcodes, 'notify' );
488
 
489
  $shortcd = array();
490
  $replace = array();
@@ -508,16 +528,17 @@ class WP_Members_Email {
508
  }
509
 
510
  // Append footer if needed.
511
- $this->settings['body'] = ( $this->settings['add_footer'] ) ? $this->settings['body'] . "\r\n" . $foot : $this->settings['body'];
512
 
513
  /**
514
  * Filters the admin notification email.
515
  *
516
  * @since 2.8.2
 
517
  *
518
  * @param string $this->settings['body'] The admin notification email body.
519
  */
520
- $this->settings['body'] = apply_filters( 'wpmem_email_notify', $this->settings['body'] );
521
 
522
  // Send the message.
523
  $this->send( 'admin' );
162
  $this->settings['disable'] = false;
163
  $this->settings['toggle'] = $this->settings['tag']; // Deprecated since 3.2.0, but remains in the array for legacy reasons.
164
  $this->settings['reset_link'] = esc_url_raw( add_query_arg( array( 'a' => 'pwdreset', 'key' => $password, 'id' => $user_id ), wpmem_profile_url() ) );
165
+ $this->settings['line_break'] = ( 1 == $this->html ) ? "<br>" : "\r\n";
166
 
167
  // Apply filters (if set) for the sending email address.
168
  $default_header = ( $this->from && $this->from_name ) ? 'From: "' . $this->from_name . '" <' . $this->from . '>' : '';
172
  *
173
  * @since 2.7.4
174
  * @since 3.2.0 Changed toggle to tag.
175
+ * @since 3.4.2 Added user ID.
176
  *
177
  * @param mixed $default_header The email headers.
178
  * @param string $this->settings['tag'] Tag to determine what email is being generated (newreg|newmod|appmod|repass|admin).
179
+ * @param int $user_id
180
  */
181
+ $this->settings['headers'] = apply_filters( 'wpmem_email_headers', $default_header, $this->settings['tag'], $this->settings['user_id'] );
182
 
183
  /**
184
  * Filters attachments.
185
  *
186
  * @since 3.4.1
187
+ * @since 3.4.2 Added user ID.
188
  *
189
  * @param mixed $attachments Any file attachments as a string or array. (default per wp_mail() documentation is empty array).
190
  * @param string $this->settings['tag'] Tag to determine what email is being generated (newreg|newmod|appmod|repass|admin).
191
+ * @param int $user_id
192
  */
193
+ $this->settings['attachments'] = apply_filters( 'wpmem_email_attachments', array(), $this->settings['tag'], $this->settings['user_id'] );
194
 
195
  /**
196
  * Filter the email.
204
  * @since 3.1.0 Added footer content to the array.
205
  * @since 3.2.0 Changed wpmem_msurl key to wpmem_profile.
206
  * @since 3.2.0 Change toggle to tag.
207
+ * @since 3.4.2 Added line_break optional param.
208
  *
209
  * @param array $this->settings {
210
  * An array containing email body, subject, user id, and additional settings.
226
  * @type bool disable
227
  * @type mixed headers
228
  * @type string toggle Deprecated since 3.2.0
229
+ * @type string line_break
230
  * }
231
  * @param array $wpmem_fields An array of the WP-Members fields.
232
  * @param array $field_data An array of the posted registration data.
243
  * @deprecated 3.2.0 Use wpmem_email_filter instead.
244
  *
245
  * @param string $this->settings['body'] The body content of the new registration email.
246
+ * @param int $user_id
247
  */
248
  $this->settings['body'] = apply_filters( 'wpmem_email_' . $this->settings['tag'], $this->settings['body'] );
249
 
281
  * Filter available email shortcodes.
282
  *
283
  * @since 3.1.0
284
+ * @since 3.4.2 Added user ID.
285
  *
286
  * @param array $shortcodes
287
  * @param string $tag
288
+ * @param int $user_id
289
  */
290
+ $shortcodes = apply_filters( 'wpmem_email_shortcodes', $shortcodes, $this->settings['tag'], $this->settings['user_id'] );
291
 
292
  $shortcd = array();
293
  $replace = array();
305
  }
306
 
307
  // Append footer if needed.
308
+ $this->settings['body'] = ( $this->settings['add_footer'] ) ? $this->settings['body'] . $this->settings['line_break'] . $foot : $this->settings['body'];
309
 
310
  // Send message.
311
  $this->send( 'user' );
357
  // Get the email stored values.
358
  $this->settings = get_option( 'wpmembers_email_notify' );
359
 
360
+ // wpautop() the content if we are doing HTML email.
361
+ if ( 1 == $this->html ) {
362
+ $this->settings['body'] = wpautop( $this->settings['body'] );
363
+ }
364
+
365
  // Userdata for default shortcodes.
366
  $this->settings['user_id'] = $user_id;
367
  $this->settings['user_login'] = stripslashes( $user->user_login );
374
  $this->settings['exp_date'] = ( defined( 'WPMEM_EXP_MODULE' ) && $wpmem->use_exp == 1 ) ? get_user_meta( $user_id, 'expires', true ) : '';
375
  $this->settings['do_shortcodes'] = true;
376
  $this->settings['add_footer'] = true;
377
+ $this->settings['footer'] = ( 1 == $this->html ) ? wpautop( get_option( 'wpmembers_email_footer' ) ) : get_option( 'wpmembers_email_footer' );
378
  $this->settings['disable'] = false;
379
+ $this->settings['line_break'] = ( 1 == $this->html ) ? "<br>" : "\r\n";
380
 
381
  // Builds an array of the user data fields.
382
  $field_arr = array();
404
  $default_header = ( $this->from && $this->from_name ) ? 'From: "' . $this->from_name . '" <' . $this->from . '>' : '';
405
 
406
  /** This filter is documented in class-wp-members-email.php */
407
+ $this->settings['headers'] = apply_filters( 'wpmem_email_headers', $default_header, 'admin', $this->settings['user_id'] );
408
 
409
  /** This filter is documented in class-wp-members-email.php */
410
+ $this->settings['attachments'] = apply_filters( 'wpmem_email_attachments', array(), 'admin', $this->settings['user_id'] );
411
 
412
  /**
413
  * Filters the address the admin notification is sent to.
414
  *
415
  * @since 2.7.5
416
+ * @since 3.4.2 Added user ID.
417
  *
418
  * @param string The email address of the admin to send to.
419
  */
420
+ $this->settings['admin_email'] = apply_filters( 'wpmem_notify_addr', get_option( 'admin_email' ), $this->settings['user_id'] );
421
 
422
  /**
423
  * Filter the email.
430
  *
431
  * @since 2.9.8
432
  * @since 3.3.9 Added $user param.
433
+ * @since 3.4.2 Added optional line_break param.
434
  *
435
  * @param array $this->settings
436
  * An array containing email body, subject, user id, and additional settings.
453
  * @type array $field_arr
454
  * @type string $headers
455
  * @type string $admin_email
456
+ * @type string $line_break
457
  * }
458
  * @param array $wpmem_fields An array of the WP-Members fields.
459
  * @param array $field_data An array of the posted registration data.
467
  // Split field_arr into field_str.
468
  $field_str = '';
469
  foreach ( $this->settings['field_arr'] as $key => $val ) {
470
+ $field_str.= $key . ': ' . $val . $this->settings['line_break'];
471
  }
472
 
473
  // Get the email footer if needed.
499
  * Filter available email shortcodes.
500
  *
501
  * @since 3.1.0
502
+ * @since 3.4.2 Added user ID.
503
  *
504
  * @param array $shortcodes
505
  * @param string $toggle
506
  */
507
+ $shortcodes = apply_filters( 'wpmem_email_shortcodes', $shortcodes, 'notify', $this->settings['user_id'] );
508
 
509
  $shortcd = array();
510
  $replace = array();
528
  }
529
 
530
  // Append footer if needed.
531
+ $this->settings['body'] = ( $this->settings['add_footer'] ) ? $this->settings['body'] . $this->settings['line_break'] . $foot : $this->settings['body'];
532
 
533
  /**
534
  * Filters the admin notification email.
535
  *
536
  * @since 2.8.2
537
+ * @since 3.4.2 Added user ID.
538
  *
539
  * @param string $this->settings['body'] The admin notification email body.
540
  */
541
+ $this->settings['body'] = apply_filters( 'wpmem_email_notify', $this->settings['body'], $this->settings['user_id'] );
542
 
543
  // Send the message.
544
  $this->send( 'admin' );
includes/class-wp-members-forms.php CHANGED
@@ -683,7 +683,7 @@ class WP_Members_Forms {
683
  * @type boolean $remember_check Default: true
684
  * @type string $n Default: "\n" (the new line character if breaks are not stripped (see $strip_breaks))
685
  * @type string $t Default: "\t" (the line indent character if breaks are not stripped (see $strip_breaks))
686
- * @type string $redirect_to Default: (the $redirec_to argument passed to the function)
687
  * @type boolean $login_form_action Default: true (if true, adds the WP login_form action)
688
  * }
689
  * @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
@@ -750,10 +750,17 @@ class WP_Members_Forms {
750
  }
751
 
752
  // Build hidden fields, filter, and add to the form.
753
- $hidden[] = wpmem_form_field( array( 'name' => 'redirect_to', 'type' => 'hidden', 'value' => esc_url( $args['redirect_to'] ) ) ) . $args['n'];
754
- $hidden[] = wpmem_form_field( array( 'name' => 'a', 'type' => 'hidden', 'value' => $action ) ) . $args['n'];
 
 
 
 
 
 
 
755
  if ( $action != 'login' ) {
756
- $hidden[] = wpmem_form_field( array( 'name' => 'formsubmit', 'type' => 'hidden', 'value' => '1' ) );
757
  }
758
 
759
  /**
@@ -768,7 +775,7 @@ class WP_Members_Forms {
768
 
769
  $hidden_field_string = '';
770
  foreach ( $hidden as $field ) {
771
- $hidden_field_string .= $field;
772
  }
773
 
774
  /**
@@ -904,6 +911,7 @@ class WP_Members_Forms {
904
  * Filter the generated HTML of the entire form.
905
  *
906
  * @since 2.7.4
 
907
  *
908
  * @param string $form The HTML of the final generated form.
909
  * @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
@@ -1571,7 +1579,7 @@ class WP_Members_Forms {
1571
  * @param array $rows
1572
  * @return string $form
1573
  */
1574
- function strip_breaks( $form, $rows ) {
1575
  foreach( $rows as $key => $row ) {
1576
  if ( 'textarea' == $row['type'] ) {
1577
  $textareas[ $key ] = $row['field'];
@@ -1981,19 +1989,12 @@ class WP_Members_Forms {
1981
  ),
1982
  'resetpassword' => array(
1983
  array(
1984
- 'name' => wpmem_get_text( 'pwdreset_username' ),
1985
  'type' => 'text',
1986
  'tag' => 'user',
1987
  'class' => 'username',
1988
  'div' => 'div_text',
1989
  ),
1990
- array(
1991
- 'name' => wpmem_get_text( 'pwdreset_email' ),
1992
- 'type' => 'text',
1993
- 'tag' => 'email',
1994
- 'class' => 'textbox',
1995
- 'div' => 'div_text',
1996
- ),
1997
  ),
1998
  'forgotusername' => array(
1999
  array(
@@ -2005,6 +2006,26 @@ class WP_Members_Forms {
2005
  ),
2006
  ),
2007
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2008
 
2009
  /**
2010
  * Filter the array of change password form fields.
@@ -2109,12 +2130,11 @@ class WP_Members_Forms {
2109
  }
2110
 
2111
  /**
2112
- * Wrapper for handing the default WP login form.
2113
  *
2114
  * @since 3.3.2
2115
  */
2116
  function wp_login_form( $args ) {
2117
-
2118
  return wp_login_form( $args );
2119
  }
2120
 
683
  * @type boolean $remember_check Default: true
684
  * @type string $n Default: "\n" (the new line character if breaks are not stripped (see $strip_breaks))
685
  * @type string $t Default: "\t" (the line indent character if breaks are not stripped (see $strip_breaks))
686
+ * @type string $redirect_to Default: (the $redirect_to argument passed to the function)
687
  * @type boolean $login_form_action Default: true (if true, adds the WP login_form action)
688
  * }
689
  * @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
750
  }
751
 
752
  // Build hidden fields, filter, and add to the form.
753
+ if ( 'set_password_from_key' == wpmem_get( 'a', false, 'request' ) && false == wpmem_get( 'formsubmit', false ) ) {
754
+ $hidden['action'] = wpmem_form_field( array( 'name' => 'a', 'type' => 'hidden', 'value' => 'set_password_from_key' ) );
755
+ $hidden['key'] = wpmem_form_field( array( 'name' => 'key', 'type' => 'hidden', 'value' => sanitize_text_field( wpmem_get( 'key', null, 'request' ) ) ) );
756
+ $hidden['login'] = wpmem_form_field( array( 'name' => 'login', 'type' => 'hidden', 'value' => sanitize_user( wpmem_get( 'login', null, 'request' ) ) ) );
757
+ } else {
758
+ $hidden['action'] = wpmem_form_field( array( 'name' => 'a', 'type' => 'hidden', 'value' => $action ) );
759
+ $hidden['redirect_to'] = wpmem_form_field( array( 'name' => 'redirect_to', 'type' => 'hidden', 'value' => esc_url( $args['redirect_to'] ) ) );
760
+ }
761
+
762
  if ( $action != 'login' ) {
763
+ $hidden['formsubmit'] = wpmem_form_field( array( 'name' => 'formsubmit', 'type' => 'hidden', 'value' => '1' ) );
764
  }
765
 
766
  /**
775
 
776
  $hidden_field_string = '';
777
  foreach ( $hidden as $field ) {
778
+ $hidden_field_string .= $field . $args['n'];
779
  }
780
 
781
  /**
911
  * Filter the generated HTML of the entire form.
912
  *
913
  * @since 2.7.4
914
+ * @since 2.9.1 Added $action argument
915
  *
916
  * @param string $form The HTML of the final generated form.
917
  * @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
1579
  * @param array $rows
1580
  * @return string $form
1581
  */
1582
+ private function strip_breaks( $form, $rows ) {
1583
  foreach( $rows as $key => $row ) {
1584
  if ( 'textarea' == $row['type'] ) {
1585
  $textareas[ $key ] = $row['field'];
1989
  ),
1990
  'resetpassword' => array(
1991
  array(
1992
+ 'name' => wpmem_get_text( 'login_username' ),
1993
  'type' => 'text',
1994
  'tag' => 'user',
1995
  'class' => 'username',
1996
  'div' => 'div_text',
1997
  ),
 
 
 
 
 
 
 
1998
  ),
1999
  'forgotusername' => array(
2000
  array(
2006
  ),
2007
  ),
2008
  );
2009
+
2010
+ // @todo Temp until 3.5.0 removes old password reset.
2011
+ if ( 1 != $wpmem->pwd_link ) {
2012
+ $input_arrays['resetpassword'] = array(
2013
+ array(
2014
+ 'name' => wpmem_get_text( 'pwdreset_username' ),
2015
+ 'type' => 'text',
2016
+ 'tag' => 'user',
2017
+ 'class' => 'username',
2018
+ 'div' => 'div_text',
2019
+ ),
2020
+ array(
2021
+ 'name' => wpmem_get_text( 'pwdreset_email' ),
2022
+ 'type' => 'text',
2023
+ 'tag' => 'email',
2024
+ 'class' => 'textbox',
2025
+ 'div' => 'div_text',
2026
+ ),
2027
+ );
2028
+ }
2029
 
2030
  /**
2031
  * Filter the array of change password form fields.
2130
  }
2131
 
2132
  /**
2133
+ * Alias for handing the default WP login form.
2134
  *
2135
  * @since 3.3.2
2136
  */
2137
  function wp_login_form( $args ) {
 
2138
  return wp_login_form( $args );
2139
  }
2140
 
includes/class-wp-members-products.php CHANGED
@@ -95,8 +95,8 @@ class WP_Members_Products {
95
  $this->load_products();
96
 
97
  add_filter( 'wpmem_securify', array( $this, 'product_access' ) );
98
- add_filter( 'wpmem_product_restricted_msg', array( $this, 'apply_custom_access_message' ) );
99
- add_filter( 'wpmem_restricted_msg', array( $this, 'apply_custom_access_message' ) );
100
  }
101
 
102
  /**
@@ -293,19 +293,24 @@ class WP_Members_Products {
293
  * @param string $msg
294
  * @return string $msg
295
  */
296
- function apply_custom_access_message( $msg ) {
297
  global $post;
298
- $post_products = $this->get_post_products( $post->ID );
 
299
  if ( $post_products ) {
 
 
300
  foreach( $post_products as $post_product ) {
301
  $membership_id = array_search( $post_product, $this->product_by_id );
302
- $message = wpautop( get_post_meta( $membership_id, 'wpmem_product_message', true ) );
303
  if ( $message ) {
304
- $product_message = ( isset( $product_message ) ) ? $product_message . $message : $message;
305
  }
306
  }
307
- if ( isset( $product_message ) ) {
308
- $msg = $product_message;
 
 
309
  }
310
  }
311
  return $msg;
95
  $this->load_products();
96
 
97
  add_filter( 'wpmem_securify', array( $this, 'product_access' ) );
98
+ add_filter( 'wpmem_product_restricted_msg', array( $this, 'apply_custom_access_message' ), 10, 2 );
99
+ add_filter( 'wpmem_restricted_msg', array( $this, 'apply_custom_access_message' ), 10, 4 );
100
  }
101
 
102
  /**
293
  * @param string $msg
294
  * @return string $msg
295
  */
296
+ function apply_custom_access_message( $msg, $mixed, $before = false, $after = false ) {
297
  global $post;
298
+ // If this is "wpmem_restricted_msg", second arg is the raw msg string, not post products
299
+ $post_products = ( ! is_array( $mixed ) && false != $before && false != $after ) ? $this->get_post_products( $post->ID ) : $mixed;
300
  if ( $post_products ) {
301
+ $product_message = false;
302
+ $count = count( $post_products );
303
  foreach( $post_products as $post_product ) {
304
  $membership_id = array_search( $post_product, $this->product_by_id );
305
+ $message = get_post_meta( $membership_id, 'wpmem_product_message', true );
306
  if ( $message ) {
307
+ $product_message = ( isset( $product_message ) ) ? $product_message . wpautop( $message ) : wpautop( $message );
308
  }
309
  }
310
+ if ( false !== $product_message ) {
311
+ $msg = ( $before ) ? '<div id="wpmem_restricted_msg">' : '';
312
+ $msg.= do_shortcode( $product_message );
313
+ $msg.= ( $after ) ? '</div>' : '';
314
  }
315
  }
316
  return $msg;
includes/class-wp-members-pwd-reset.php CHANGED
@@ -12,9 +12,10 @@ class WP_Members_Pwd_Reset {
12
  *
13
  * @since 3.3.5
14
  */
15
- public $form_submitted_key_not_found;
16
- public $form_load_key_not_found;
17
- public $key_is_expired;
 
18
 
19
  /**
20
  * Meta containers
@@ -35,6 +36,7 @@ class WP_Members_Pwd_Reset {
35
  'form_submitted_key_not_found' => __( "Sorry, no password reset key was found. Please check your email and try again.", 'wp-members' ),
36
  'form_load_key_not_found' => __( "Sorry, no password reset key was found. Please check your email and try again.", 'wp-members' ),
37
  'key_is_expired' => __( "Sorry, the password reset key is expired.", 'wp-members' ),
 
38
  );
39
 
40
  /**
@@ -42,7 +44,9 @@ class WP_Members_Pwd_Reset {
42
  *
43
  * @since 3.3.8
44
  *
45
- * @param array $defaults
 
 
46
  */
47
  $defaults = apply_filters( 'wpmem_pwd_reset_default_dialogs', $defaults );
48
 
@@ -50,12 +54,8 @@ class WP_Members_Pwd_Reset {
50
  $this->{$key} = $value;
51
  }
52
 
53
- add_filter( 'wpmem_email_filter', array( $this, 'add_reset_key_to_email' ), 10, 3 );
54
- add_filter( 'the_content', array( $this, 'display_content' ), 100 );
55
- add_filter( 'wpmem_login_hidden_fields', array( $this, 'add_hidden_form_field' ), 10, 2 );
56
- add_action( 'wpmem_get_action', array( $this, 'get_wpmem_action' ) );
57
- add_filter( 'wpmem_regchk', array( $this, 'change_regchk' ), 10, 2 );
58
- add_filter( 'wpmem_resetpassword_form_defaults', array( $this, 'reset_password_form' ) );
59
  }
60
 
61
  /**
@@ -75,7 +75,7 @@ class WP_Members_Pwd_Reset {
75
  $user = get_user_by( 'ID', $arr['user_id'] );
76
 
77
  // Get the stored key.
78
- $key = $this->get_password_reset_key( $user );
79
  $query_args = array(
80
  'a' => $this->form_action,
81
  'key' => $key,
@@ -112,7 +112,7 @@ class WP_Members_Pwd_Reset {
112
 
113
  global $wpmem;
114
 
115
- if ( ! is_user_logged_in() && in_the_loop() && $this->form_action == wpmem_get( 'a', false, 'request' ) ) {
116
  // Define variables
117
  $result = '';
118
  $user_id = false;
@@ -182,7 +182,7 @@ class WP_Members_Pwd_Reset {
182
  if ( 'invalid_key' == $user->get_error_code() ) {
183
  // If somehow the form was submitted but the key not found.
184
  $pwd_reset_link = wpmem_profile_url( 'pwdreset' );
185
- $msg = wpmem_get_display_message( 'invalid_key', $this->form_submitted_key_not_found . '<br /><a href="' . $pwd_reset_link . '">Request a new reset key.</a>' );
186
  $form = '';
187
  } else {
188
  $form = wpmem_change_password_form();
@@ -195,108 +195,4 @@ class WP_Members_Pwd_Reset {
195
 
196
  return $content;
197
  }
198
-
199
- /**
200
- * Add hidden form field for form action.
201
- *
202
- * @since 3.3.5
203
- *
204
- * @param string $hidden_fields
205
- * @return string $hidden_fields
206
- */
207
- function add_hidden_form_field( $hidden_fields, $action ) {
208
- if ( $this->form_action == wpmem_get( 'a', false, 'request' ) ) {
209
- $hidden_fields = str_replace( 'pwdchange', $this->form_action, $hidden_fields );
210
- $hidden_fields.= wpmem_form_field( array( 'name' => 'key', 'type' => 'hidden', 'value' => sanitize_text_field( wpmem_get( 'key', null, 'request' ) ) ) );
211
- $hidden_fields.= wpmem_form_field( array( 'name' => 'login', 'type' => 'hidden', 'value' => sanitize_user( wpmem_get( 'login', null, 'request' ) ) ) );
212
- }
213
- return $hidden_fields;
214
- }
215
-
216
- /**
217
- * Get the wpmem action variable.
218
- *
219
- * @since 3.3.5
220
- */
221
- function get_wpmem_action() {
222
- global $wpmem;
223
- if ( 'pwdreset' == $wpmem->action && isset( $_POST['formsubmit'] ) ) {
224
-
225
- if ( ! wp_verify_nonce( $_REQUEST['_wpmem_pwdreset_nonce'], 'wpmem_shortform_nonce' ) ) {
226
- return "reg_generic";
227
- }
228
-
229
- $user_to_check = wpmem_get( 'user', false );
230
- $user_to_check = ( strpos( $user_to_check, '@' ) ) ? sanitize_email( $user_to_check ) : sanitize_user( $user_to_check );
231
-
232
- if ( username_exists( $user_to_check ) ) {
233
- $user = get_user_by( 'login', $user_to_check );
234
- if ( ( 1 == $wpmem->mod_reg ) && ( 1 != get_user_meta( $user->ID, 'active', true ) ) ) {
235
- $user = false;
236
- }
237
- } elseif ( email_exists( $user_to_check ) ) {
238
- $user = get_user_by( 'email', $user_to_check );
239
- } else {
240
- $user = false;
241
- }
242
-
243
- if ( false === $user ) {
244
- return "pwdreseterr";
245
- }
246
-
247
- $new_pass = '';
248
- wpmem_email_to_user( $user->ID, $new_pass, 3 );
249
- /** This action is documented in /includes/class-wp-members-user.php */
250
- do_action( 'wpmem_pwd_reset', $user->ID, $new_pass );
251
- $wpmem->action = 'pwdreset_link';
252
- $wpmem->regchk = 'pwdresetsuccess';
253
- return "pwdresetsuccess";
254
- }
255
- return;
256
- }
257
-
258
- /**
259
- * Changes the wpmem_regchk value.
260
- *
261
- * @since 3.3.5
262
- *
263
- * @param string $regchk
264
- */
265
- function change_regchk( $regchk, $action ) {
266
- global $wpmem;
267
- if ( 'pwdreset_link' == $action && 'pwdresetsuccess' == $wpmem->regchk ) {
268
- global $wpmem;
269
- $wpmem->action = 'pwdreset';
270
- return 'pwdresetsuccess';
271
- }
272
- return $regchk;
273
- }
274
-
275
- /**
276
- * Filter the reset password form.
277
- *
278
- * @since 3.3.5
279
- *
280
- * @param array $args
281
- */
282
- function reset_password_form( $args ) {
283
- global $wpmem;
284
- $args['inputs'][0]['name'] = wpmem_get_text( 'login_username' );
285
- unset( $args['inputs'][1] );
286
- return $args;
287
- }
288
-
289
- /**
290
- * Sets and gets the password reset key.
291
- *
292
- * This function is an alias for the WP function get_password_reset_key().
293
- *
294
- * @since 3.3.8
295
- *
296
- * @param object $user
297
- * @return string The reset key.
298
- */
299
- private function get_password_reset_key( $user ) {
300
- return get_password_reset_key( $user );
301
- }
302
  }
12
  *
13
  * @since 3.3.5
14
  */
15
+ public $form_submitted_key_not_found;
16
+ public $form_load_key_not_found;
17
+ public $key_is_expired;
18
+ private $reset_key;
19
 
20
  /**
21
  * Meta containers
36
  'form_submitted_key_not_found' => __( "Sorry, no password reset key was found. Please check your email and try again.", 'wp-members' ),
37
  'form_load_key_not_found' => __( "Sorry, no password reset key was found. Please check your email and try again.", 'wp-members' ),
38
  'key_is_expired' => __( "Sorry, the password reset key is expired.", 'wp-members' ),
39
+ 'request_new_key' => __( "Request a new reset key.", 'wp-members' ),
40
  );
41
 
42
  /**
44
  *
45
  * @since 3.3.8
46
  *
47
+ * @param array $defaults {
48
+ *
49
+ * }
50
  */
51
  $defaults = apply_filters( 'wpmem_pwd_reset_default_dialogs', $defaults );
52
 
54
  $this->{$key} = $value;
55
  }
56
 
57
+ add_filter( 'wpmem_email_filter', array( $this, 'add_reset_key_to_email' ), 10, 3 );
58
+ add_filter( 'the_content', array( $this, 'display_content' ), 100 );
 
 
 
 
59
  }
60
 
61
  /**
75
  $user = get_user_by( 'ID', $arr['user_id'] );
76
 
77
  // Get the stored key.
78
+ $key = get_password_reset_key( $user );
79
  $query_args = array(
80
  'a' => $this->form_action,
81
  'key' => $key,
112
 
113
  global $wpmem;
114
 
115
+ if ( ! is_user_logged_in() && $this->form_action == wpmem_get( 'a', false, 'request' ) && ! is_admin() ) {
116
  // Define variables
117
  $result = '';
118
  $user_id = false;
182
  if ( 'invalid_key' == $user->get_error_code() ) {
183
  // If somehow the form was submitted but the key not found.
184
  $pwd_reset_link = wpmem_profile_url( 'pwdreset' );
185
+ $msg = wpmem_get_display_message( 'invalid_key', $this->form_submitted_key_not_found . '<br /><a href="' . $pwd_reset_link . '">' . $this->request_new_key . '</a>' );
186
  $form = '';
187
  } else {
188
  $form = wpmem_change_password_form();
195
 
196
  return $content;
197
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  }
includes/class-wp-members-shortcodes.php CHANGED
@@ -93,6 +93,10 @@ class WP_Members_Shortcodes {
93
  */
94
  function forms( $atts, $content, $tag ) {
95
 
 
 
 
 
96
  global $wpmem, $wpmem_themsg;
97
 
98
  // Defaults.
@@ -113,7 +117,14 @@ class WP_Members_Shortcodes {
113
  switch ( $atts['form'] ) {
114
 
115
  case 'wp_login':
116
- $content = wpmem_wp_login_form( $atts );
 
 
 
 
 
 
 
117
  break;
118
 
119
  case 'register':
@@ -218,6 +229,9 @@ class WP_Members_Shortcodes {
218
  * @tryp string $compare Can specify a comparison operator when using meta_key/meta_value (optional).
219
  * @type string $product If the user has a specific product/membership (optional).
220
  * @type string $membership If the user has a specific product/membership (optional).
 
 
 
221
  * }
222
  * @param string $content Shortcode content.
223
  * @param string $tag The shortcode's tag (wpmem_logged_in).
@@ -329,6 +343,16 @@ class WP_Members_Shortcodes {
329
  $do_return = false;
330
  }
331
 
 
 
 
 
 
 
 
 
 
 
332
  }
333
 
334
  // Return content (or empty content) depending on the result of the above logic.
@@ -857,7 +881,7 @@ class WP_Members_Shortcodes {
857
  // If the password shortcode page is set as User Profile page.
858
  if ( 'getusername' == $wpmem->action ) {
859
 
860
- return wpmem_page_forgot_username( $wpmem_regchk, $content );
861
 
862
  } else {
863
 
93
  */
94
  function forms( $atts, $content, $tag ) {
95
 
96
+ if ( is_admin() ) {
97
+ return;
98
+ }
99
+
100
  global $wpmem, $wpmem_themsg;
101
 
102
  // Defaults.
117
  switch ( $atts['form'] ) {
118
 
119
  case 'wp_login':
120
+ if ( is_user_logged_in() && '1' != $customizer ) {
121
+ // If the user is logged in, return any nested content (if any) or the default bullet links if no nested content.
122
+ $content = ( $content ) ? $content : $this->render_links( 'login' );
123
+ } else {
124
+ $atts['echo'] = false;
125
+ $atts['redirect'] = ( isset( $atts['redirect'] ) ) ? $atts['redirect'] : ( ( isset( $atts['redirect_to'] ) ) ? $atts['redirect_to'] : wpmem_current_url() );
126
+ $content = wpmem_wp_login_form( $atts );
127
+ }
128
  break;
129
 
130
  case 'register':
229
  * @tryp string $compare Can specify a comparison operator when using meta_key/meta_value (optional).
230
  * @type string $product If the user has a specific product/membership (optional).
231
  * @type string $membership If the user has a specific product/membership (optional).
232
+ * @type string $wrap_id Adds a div wrapper with specified id.
233
+ * @type string $wrap_class Adds a div wrapper with specified class.
234
+ * @type string $wrap_tag Specifies wrapper tag (default: div)
235
  * }
236
  * @param string $content Shortcode content.
237
  * @param string $tag The shortcode's tag (wpmem_logged_in).
343
  $do_return = false;
344
  }
345
 
346
+ // Adds optional wrapper.
347
+ if ( isset( $atts['wrap_id'] ) || isset( $atts['wrap_class'] ) ) {
348
+ $tag = ( isset( $atts['wrap_tag'] ) ) ? $atts['wrap_tag'] : 'div';
349
+ $wrapper = '<' . $tag;
350
+ $wrapper .= ( isset( $atts['wrap_id'] ) ) ? ' id="' . $atts['wrap_id'] . '"' : '';
351
+ $wrapper .= ( isset( $atts['wrap_class'] ) ) ? ' class="' . $atts['wrap_class'] . '"' : '';
352
+ $wrapper .= '>';
353
+ $content = $wrapper . $content . '</' . $tag . '>';
354
+ }
355
+
356
  }
357
 
358
  // Return content (or empty content) depending on the result of the above logic.
881
  // If the password shortcode page is set as User Profile page.
882
  if ( 'getusername' == $wpmem->action ) {
883
 
884
+ return $this->render_forgot_username( $wpmem_regchk, $content );
885
 
886
  } else {
887
 
includes/class-wp-members-user.php CHANGED
@@ -611,13 +611,19 @@ class WP_Members_User {
611
  'user' => sanitize_user( wpmem_get( 'user', false ) ),
612
  'email' => sanitize_email( wpmem_get( 'email', false ) ),
613
  );
 
 
 
 
 
 
614
  } else {
615
  $args = array(
616
  'pass1' => wpmem_get( 'pass1', false ),
617
  'pass2' => wpmem_get( 'pass2', false ),
618
  );
 
619
  }
620
- return ( 'reset' == $action ) ? $this->password_reset( $args ) : $this->password_change( $args );
621
  }
622
  return;
623
  }
@@ -726,6 +732,53 @@ class WP_Members_User {
726
  }
727
  return;
728
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
729
 
730
  /**
731
  * Handles retrieving a forgotten username.
@@ -901,7 +954,7 @@ class WP_Members_User {
901
  }
902
 
903
  // Product must be an array.
904
- $product_array = ( ! is_array( $product ) ) ? array( $product ) : $product;
905
 
906
  $product_array = $this->get_membership_stack( $product_array );
907
 
@@ -1012,7 +1065,15 @@ class WP_Members_User {
1012
  * @global object $wpmem
1013
  *
1014
  * @param int $user_id
1015
- * @return array $products
 
 
 
 
 
 
 
 
1016
  */
1017
  function get_user_products( $user_id = false, $obj = false ) {
1018
  global $wpmem;
@@ -1081,6 +1142,9 @@ class WP_Members_User {
1081
  *
1082
  * @param int $user_id
1083
  * @param string $product
 
 
 
1084
  */
1085
  do_action( 'wpmem_user_product_set', $user_id, $product, $new_value, $prev_value, $renew );
1086
 
@@ -1160,7 +1224,7 @@ class WP_Members_User {
1160
  */
1161
  function check_activated( $user, $username, $password ) {
1162
  // Password must be validated.
1163
- $pass = ( ( ! is_wp_error( $user ) ) && $password ) ? wp_check_password( $password, $user->user_pass, $user->ID ) : false;
1164
 
1165
  if ( ! $pass ) {
1166
  return $user;
611
  'user' => sanitize_user( wpmem_get( 'user', false ) ),
612
  'email' => sanitize_email( wpmem_get( 'email', false ) ),
613
  );
614
+ return $this->password_reset( $args );
615
+ } elseif( 'link' == $action ) {
616
+ $user = wpmem_get( 'user', false );
617
+ $user = ( strpos( $user, '@' ) ) ? sanitize_email( $user ) : sanitize_user( $user );
618
+ $args = array( 'user' => $user );
619
+ return $this->password_link( $args );
620
  } else {
621
  $args = array(
622
  'pass1' => wpmem_get( 'pass1', false ),
623
  'pass2' => wpmem_get( 'pass2', false ),
624
  );
625
+ return $this->password_change( $args );
626
  }
 
627
  }
628
  return;
629
  }
732
  }
733
  return;
734
  }
735
+
736
+ function password_link( $args ) {
737
+ global $wpmem;
738
+ /**
739
+ * Filter the password reset arguments.
740
+ *
741
+ * @since 3.4.2
742
+ *
743
+ * @param array The username or email.
744
+ */
745
+ $arr = apply_filters( 'wpmem_pwdreset_args', $args );
746
+ if ( ! isset( $arr['user'] ) || '' == $arr['user'] ) {
747
+ // There was an empty field.
748
+ return "pwdreseterr";
749
+
750
+ } else {
751
+
752
+ if ( ! wp_verify_nonce( $_REQUEST['_wpmem_pwdreset_nonce'], 'wpmem_shortform_nonce' ) ) {
753
+ return "reg_generic";
754
+ }
755
+
756
+ $user_to_check = ( strpos( $user_to_check, '@' ) ) ? sanitize_email( $arr['user'] ) : sanitize_user( $arr['user'] );
757
+
758
+ if ( username_exists( $user_to_check ) ) {
759
+ $user = get_user_by( 'login', $user_to_check );
760
+ if ( ( 1 == $wpmem->mod_reg ) && ( 1 != get_user_meta( $user->ID, 'active', true ) ) ) {
761
+ $user = false;
762
+ }
763
+ } elseif ( email_exists( $user_to_check ) ) {
764
+ $user = get_user_by( 'email', $user_to_check );
765
+ } else {
766
+ $user = false;
767
+ }
768
+
769
+ if ( $user ) {
770
+ wpmem_email_to_user( $user->ID, '', 3 );
771
+ /** This action is documented in /includes/class-wp-members-user.php */
772
+ do_action( 'wpmem_pwd_reset', $user->ID, '' );
773
+ return "pwdresetsuccess";
774
+
775
+ } else {
776
+ // Username did not exist.
777
+ return "pwdreseterr";
778
+ }
779
+ }
780
+ return;
781
+ }
782
 
783
  /**
784
  * Handles retrieving a forgotten username.
954
  }
955
 
956
  // Product must be an array.
957
+ $product_array = ( ! is_array( $product ) ) ? explode( ",", $product ) : $product;
958
 
959
  $product_array = $this->get_membership_stack( $product_array );
960
 
1065
  * @global object $wpmem
1066
  *
1067
  * @param int $user_id
1068
+ * @return array $products {
1069
+ * Memberships the user has as an array keyed by the membership slug.
1070
+ * Memberships the user does not have enabled are not in the array.
1071
+ * If a memberships is an expiration product, the expiration is the
1072
+ * value as a timestamp (epoch time). Note that access can be checked
1073
+ * with wpmem_user_has_access() or wpmem_user_is_expired().
1074
+ *
1075
+ * @type mixed 1|timestamp
1076
+ * }
1077
  */
1078
  function get_user_products( $user_id = false, $obj = false ) {
1079
  global $wpmem;
1142
  *
1143
  * @param int $user_id
1144
  * @param string $product
1145
+ * @param mixed $new_value
1146
+ * @param string $prev_value
1147
+ * @param bool $renew
1148
  */
1149
  do_action( 'wpmem_user_product_set', $user_id, $product, $new_value, $prev_value, $renew );
1150
 
1224
  */
1225
  function check_activated( $user, $username, $password ) {
1226
  // Password must be validated.
1227
+ $pass = ( ! is_wp_error( $user ) && ! is_null( $user ) && $password ) ? wp_check_password( $password, $user->user_pass, $user->ID ) : false;
1228
 
1229
  if ( ! $pass ) {
1230
  return $user;
includes/class-wp-members-validation-link.php CHANGED
@@ -381,6 +381,6 @@ class WP_Members_Validation_Link {
381
  * @param string time()
382
  * @param string $key
383
  */
384
- do_action( 'wpmem_user_set_as_unconfirmed', $user_id, time(), $key );
385
  }
386
  }
381
  * @param string time()
382
  * @param string $key
383
  */
384
+ do_action( 'wpmem_user_set_as_unconfirmed', $user_id, time(), $validation_key );
385
  }
386
  }
includes/class-wp-members.php CHANGED
@@ -338,6 +338,13 @@ class WP_Members {
338
  * @var string
339
  */
340
  public $upload_base = 'wpmembers';
 
 
 
 
 
 
 
341
 
342
  /**
343
  * Plugin initialization function.
@@ -356,6 +363,18 @@ class WP_Members {
356
  // Load dependent files.
357
  $this->load_dependencies();
358
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  /**
360
  * Filter the options before they are loaded into constants.
361
  *
@@ -364,26 +383,15 @@ class WP_Members {
364
  *
365
  * @param array $this->settings An array of the WP-Members settings.
366
  */
367
- $settings = apply_filters( 'wpmem_settings', get_option( 'wpmembers_settings' ) );
368
 
369
- // Validate that v3 settings are loaded.
370
- if ( ! isset( $settings['version'] )
371
- || $settings['version'] != $this->version
372
- || ! isset( $settings['db_version'] )
373
- || $settings['db_version'] != $this->db_version ) {
374
- /**
375
- * Load installation routine.
376
- */
377
- require_once( $this->path . 'includes/install.php' );
378
- // Update settings.
379
- /** This filter is documented in /inc/class-wp-members.php */
380
- $settings = apply_filters( 'wpmem_settings', wpmem_do_install() );
381
- }
382
-
383
  // Assemble settings.
384
  foreach ( $settings as $key => $val ) {
385
  $this->$key = $val;
386
  }
 
 
 
387
 
388
  $this->load_user_pages();
389
  $this->set_style();
@@ -460,18 +468,16 @@ class WP_Members {
460
 
461
  add_action( 'init', array( $this, 'load_textdomain' ) );
462
  add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
 
463
  add_action( 'widgets_init', array( $this, 'widget_init' ) ); // initializes the widget
464
- add_action( 'admin_init', array( $this, 'load_admin' ) ); // check user role to load correct dashboard
465
  add_action( 'rest_api_init', array( $this, 'rest_init' ) );
 
 
466
  add_action( 'template_redirect', array( $this, 'get_action' ) );
467
-
468
  add_action( 'login_enqueue_scripts', array( $this, 'enqueue_style_wp_login' ) ); // styles the native registration
469
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) ); // Enqueues the stylesheet.
470
  add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
471
-
472
- add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ), 20 );
473
  add_action( 'customize_register', array( $this, 'customizer_settings' ) );
474
- add_action( 'admin_menu', 'wpmem_admin_options' ); // Adds admin menu
475
  add_action( 'wp_footer', array( $this, 'invisible_captcha' ) );
476
 
477
  if ( is_user_logged_in() ) {
@@ -713,8 +719,9 @@ class WP_Members {
713
  * Fires when the wpmem action is retrieved.
714
  *
715
  * @since 3.1.7
 
716
  */
717
- do_action( 'wpmem_get_action' );
718
 
719
  // Get the regchk value (if any).
720
  $this->regchk = $this->get_regchk( $this->action );
@@ -749,11 +756,17 @@ class WP_Members {
749
  break;
750
 
751
  case 'pwdchange':
 
752
  $regchk = $this->user->password_update( 'change' );
753
  break;
754
 
755
  case 'pwdreset':
756
- $regchk = $this->user->password_update( 'reset' );
 
 
 
 
 
757
  break;
758
 
759
  case 'getusername':
@@ -1766,7 +1779,7 @@ class WP_Members {
1766
  $html.= ( is_user_logged_in() ) ? '<input type="hidden" name="a" value="logout" />' : '';
1767
  $html.= '<input type="submit" value="' . $text . '" /></form>';
1768
  } else {
1769
- $html = sprintf( '<a href="%s" id="%" class="%s">%s</a>', $link, $args['id'], $args['class'], $text );
1770
  }
1771
  return $html;
1772
  }
338
  * @var string
339
  */
340
  public $upload_base = 'wpmembers';
341
+
342
+ /**
343
+ * Opt in to update and security notifications.
344
+ *
345
+ * @since 3.4.2
346
+ */
347
+ public $optin;
348
 
349
  /**
350
  * Plugin initialization function.
363
  // Load dependent files.
364
  $this->load_dependencies();
365
 
366
+ $settings = get_option( 'wpmembers_settings' );
367
+
368
+ // Validate that v3 settings are loaded.
369
+ if ( ! isset( $settings['version'] )
370
+ || $settings['version'] != $this->version
371
+ || ! isset( $settings['db_version'] )
372
+ || $settings['db_version'] != $this->db_version ) {
373
+ // Load installation routine and pdate settings.
374
+ require_once( $this->path . 'includes/install.php' );
375
+ $settings = wpmem_do_install();
376
+ }
377
+
378
  /**
379
  * Filter the options before they are loaded into constants.
380
  *
383
  *
384
  * @param array $this->settings An array of the WP-Members settings.
385
  */
386
+ $settings = apply_filters( 'wpmem_settings', $settings );
387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  // Assemble settings.
389
  foreach ( $settings as $key => $val ) {
390
  $this->$key = $val;
391
  }
392
+
393
+ // @todo Until I think of a better place to put this.
394
+ $this->optin = get_option( 'wpmembers_optin' );
395
 
396
  $this->load_user_pages();
397
  $this->set_style();
468
 
469
  add_action( 'init', array( $this, 'load_textdomain' ) );
470
  add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
471
+ add_action( 'init', array( $this, 'load_admin' ) ); // @todo Check user role to load correct dashboard
472
  add_action( 'widgets_init', array( $this, 'widget_init' ) ); // initializes the widget
 
473
  add_action( 'rest_api_init', array( $this, 'rest_init' ) );
474
+ add_action( 'admin_menu', 'wpmem_admin_options' ); // Adds admin menu
475
+ add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ), 20 );
476
  add_action( 'template_redirect', array( $this, 'get_action' ) );
 
477
  add_action( 'login_enqueue_scripts', array( $this, 'enqueue_style_wp_login' ) ); // styles the native registration
478
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) ); // Enqueues the stylesheet.
479
  add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
 
 
480
  add_action( 'customize_register', array( $this, 'customizer_settings' ) );
 
481
  add_action( 'wp_footer', array( $this, 'invisible_captcha' ) );
482
 
483
  if ( is_user_logged_in() ) {
719
  * Fires when the wpmem action is retrieved.
720
  *
721
  * @since 3.1.7
722
+ * @since 3.4.2 Added action as a param.
723
  */
724
+ do_action( 'wpmem_get_action', $this->action );
725
 
726
  // Get the regchk value (if any).
727
  $this->regchk = $this->get_regchk( $this->action );
756
  break;
757
 
758
  case 'pwdchange':
759
+ case 'set_password_from_key':
760
  $regchk = $this->user->password_update( 'change' );
761
  break;
762
 
763
  case 'pwdreset':
764
+ global $wpmem;
765
+ if ( 1 == $wpmem->pwd_link ) {
766
+ $regchk = $this->user->password_update( 'link' );
767
+ } else {
768
+ $regchk = $this->user->password_update( 'reset' );
769
+ }
770
  break;
771
 
772
  case 'getusername':
1779
  $html.= ( is_user_logged_in() ) ? '<input type="hidden" name="a" value="logout" />' : '';
1780
  $html.= '<input type="submit" value="' . $text . '" /></form>';
1781
  } else {
1782
+ $html = sprintf( '<a href="%s" id="%s" class="%s">%s</a>', $link, $args['id'], $args['class'], $text );
1783
  }
1784
  return $html;
1785
  }
includes/deprecated.php CHANGED
@@ -554,7 +554,7 @@ endif;
554
  * This function creates a form for retrieving a forgotten username.
555
  *
556
  * @since 3.0.8
557
- * @deprecated 3.4.0 Use $wpmem->shortcodes->do_forgot_username() instead.
558
  *
559
  * @param string $wpmem_regchk
560
  * @param string $content
554
  * This function creates a form for retrieving a forgotten username.
555
  *
556
  * @since 3.0.8
557
+ * @deprecated 3.4.0 Use $wpmem->shortcodes->render_forgot_username() instead.
558
  *
559
  * @param string $wpmem_regchk
560
  * @param string $content
includes/install.php CHANGED
@@ -47,7 +47,7 @@ function wpmem_do_install() {
47
 
48
  $existing_settings = get_option( 'wpmembers_settings' );
49
 
50
- if ( false === $existing_settings || $chk_force == true ) {
51
 
52
  // New install.
53
  $wpmem_settings = wpmem_install_settings();
@@ -84,6 +84,9 @@ function wpmem_do_install() {
84
  if ( version_compare( $existing_settings['db_version'], '2.3.0', '<' ) ) {
85
  wpmem_upgrade_hidden_transient();
86
  }
 
 
 
87
  }
88
 
89
  return $wpmem_settings;
@@ -523,6 +526,9 @@ function wpmem_install_settings() {
523
 
524
  // Using update_option to allow for forced update.
525
  update_option( 'wpmembers_settings', $wpmem_settings, '', 'yes' );
 
 
 
526
 
527
  return $wpmem_settings;
528
  }
@@ -768,4 +774,68 @@ function wpmem_upgrade_hidden_transient() {
768
  $temp_obj->update_hidden_posts();
769
  delete_transient( '_wpmem_hidden_posts' );
770
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
  // End of file.
47
 
48
  $existing_settings = get_option( 'wpmembers_settings' );
49
 
50
+ if ( false == $existing_settings || $chk_force == true ) {
51
 
52
  // New install.
53
  $wpmem_settings = wpmem_install_settings();
84
  if ( version_compare( $existing_settings['db_version'], '2.3.0', '<' ) ) {
85
  wpmem_upgrade_hidden_transient();
86
  }
87
+
88
+ // If this is an upgrade, check for correct onboarding.
89
+ update_option( 'wpmembers_install_state', 'update_pending' );
90
  }
91
 
92
  return $wpmem_settings;
526
 
527
  // Using update_option to allow for forced update.
528
  update_option( 'wpmembers_settings', $wpmem_settings, '', 'yes' );
529
+
530
+ // This is a new install.
531
+ update_option( 'wpmembers_install_state', 'new_install' );
532
 
533
  return $wpmem_settings;
534
  }
774
  $temp_obj->update_hidden_posts();
775
  delete_transient( '_wpmem_hidden_posts' );
776
  }
777
+
778
+ function wpmem_onboarding_init( $action ) {
779
+ global $wpmem, $wpmem_onboarding;
780
+ include_once( 'vendor/rocketgeek-tools/class-rocketgeek-onboarding.php' );
781
+ $settings = array(
782
+ 'page_title' => 'WP-Members Onboarding',
783
+ 'menu_title' => 'WP-Members Onboarding',
784
+ 'capability' => 'manage_options',
785
+ 'menu_slug' => 'wp-members-onboarding',
786
+ 'product_slug' => 'wp-members',
787
+ 'product_file' => $wpmem->path . 'wp-members.php',
788
+ 'product_action' => $action,
789
+ 'product_type' => 'plugin',
790
+ 'opt_in_callback' => 'wpmem_onboarding_opt_in',
791
+ 'opt_in_callback_args' => array(),
792
+ );
793
+ $wpmem_onboarding = new RocketGeek_Onboarding_Beta( $settings );
794
+ }
795
+
796
+ function wpmem_onboarding_new_install( $path, $version ) {
797
+ global $wpmem_onboarding;
798
+ wpmem_onboarding_init( 'install' );
799
+ }
800
+
801
+ function wpmem_onboarding_pending_update( $path, $version ) {
802
+ global $wpmem_onboarding;
803
+ wpmem_onboarding_init( 'update' );
804
+ }
805
+
806
+ function wpmem_onboarding_opt_in() {
807
+ global $wpmem, $wpmem_onboarding;
808
+ // $onboarding_title = ( 'upgrade' == $args['param1'] ) ? __( 'WP-Members Upgrade', 'wp-members' ) : __( "WP-Members New Install", 'wp-members' );
809
+ $install_state = get_option( 'wpmembers_install_state' );
810
+ $onboarding_title = ( 'update_pending' == $install_state ) ? __( 'WP-Members Upgrade', 'wp-members' ) : __( "WP-Members New Install", 'wp-members' );
811
+ $onboarding_release_notes = "https://rocketgeek.com/release-notes/wp-members-3-4-2/";
812
+ $onboarding_version = $wpmem->version;
813
+
814
+ $page = ( ! isset( $_POST['step'] ) ) ? 'step_1' : $_POST['step'];
815
+ if ( 'finalize' == $page ) {
816
+ if ( isset( $_POST['optin'] ) ) {
817
+ if ( 'update_pending' == $install_state ) {
818
+ $wpmem_onboarding->record_plugin_upgrade( 'wp-members', $wpmem->path . 'wp-members.php' );
819
+ } else {
820
+ $wpmem_onboarding->record_plugin_activation( 'wp-members', $wpmem->path . 'wp-members.php' );
821
+ }
822
+ update_option( 'wpmembers_optin', 1 );
823
+ } else {
824
+ update_option( 'wpmembers_optin', 0 );
825
+ }
826
+
827
+ update_option( 'wpmembers_install_state', 'install_complete_' . $wpmem->version . '_' . time() );
828
+ include_once( $wpmem->path . 'includes/admin/partials/onboarding_finalize.php' );
829
+ }
830
+ exit();
831
+ }
832
+
833
+ function wpmem_plugin_deactivate() {
834
+ global $wpmem, $wpmem_onboarding;
835
+ $optin = get_option( 'wpmembers_optin' );
836
+ if ( 1 == $optin ) {
837
+ wpmem_onboarding_init( 'deactivate' );
838
+ $wpmem_onboarding->record_plugin_deactivation( 'wp-members', $wpmem->path . 'wp-members.php' );
839
+ }
840
+ }
841
  // End of file.
includes/vendor/rocketgeek-tools/assets/css/onboarding.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpmem_onboarding .wrapper {
2
+ width:760px;
3
+ margin:100px auto 0;
4
+ padding: 20px;
5
+ border: 1px solid;
6
+ background-color: #fff;
7
+ }
8
+
9
+ #wpmem_onboarding .section_lead {
10
+ font-size: 18px;
11
+ line-height: 1.75;
12
+ margin: 40px 0;
13
+ }
14
+
15
+ #wpmem_onboarding h3 {
16
+ margin:60px 0 0 0;
17
+ }
18
+
19
+ #wpmem_onboarding .setting {
20
+ margin: 0 0 40px 0;
21
+ }
22
+
23
+ #wpmem_onboarding .dashicons-yes {
24
+ color: green;
25
+ font-size: 30px;
26
+ vertical-align: text-bottom;
27
+ margin: 0 10px;
28
+ }
29
+
30
+ #wpmem_onboarding .setting_match {
31
+ font-weight: bold;
32
+ }
33
+
34
+ #wpmem_onboarding .current {
35
+ color: green;
36
+ }
includes/vendor/rocketgeek-tools/class-rocketgeek-onboarding.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class RocketGeek_Onboarding_Beta {
4
+
5
+ public function __construct( $settings ) {
6
+ $this->settings = $settings;
7
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
8
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
9
+ }
10
+
11
+ public function enqueue_scripts() {
12
+ wp_register_style( 'rktgk_onboarding_css', plugin_dir_url( __FILE__ ) . 'assets/css/onboarding.css', false, '1.0.0' );
13
+ wp_enqueue_style( 'rktgk_onboarding_css' );
14
+ }
15
+
16
+ public function record_plugin_activation( $slug, $product_file ) {
17
+ require_once( plugin_dir_path( __FILE__ ) . 'class-rocketgeek-satellite.php' );
18
+ $rgut = new RocketGeek_Satellite_Beta( $slug, $product_file, 'activate', 'plugin' );
19
+ }
20
+
21
+ public function record_plugin_deactivation( $slug, $product_file ) {
22
+ require_once( plugin_dir_path( __FILE__ ) . 'class-rocketgeek-satellite.php' );
23
+ $rgut = new RocketGeek_Satellite_Beta( $slug, $product_file, 'deactivate', 'plugin' );
24
+ }
25
+
26
+ public function record_plugin_upgrade( $slug, $product_file ) {
27
+ require_once( plugin_dir_path( __FILE__ ) . 'class-rocketgeek-satellite.php' );
28
+ $rgut = new RocketGeek_Satellite_Beta( $slug, $product_file, 'update', 'plugin' );
29
+ }
30
+
31
+ public function admin_menu () {
32
+ add_submenu_page( null, $this->settings['page_title'], $this->settings['menu_title'], $this->settings['capability'], $this->settings['menu_slug'], array( $this, 'do_options_page' ) );
33
+ }
34
+
35
+ public function do_options_page() {
36
+ // @todo Get install record to check if this is a new install or update.
37
+ call_user_func_array( $this->settings['opt_in_callback'], $this->settings['opt_in_callback_args'] );
38
+ }
39
+ }
includes/vendor/rocketgeek-tools/class-rocketgeek-satellite.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! class_exists( 'RocketGeek_Satellite_Beta' ) ) :
3
+ class RocketGeek_Satellite_Beta {
4
+
5
+ var $version = "1.0.2";
6
+ var $api_domain = 'https://rocketgeek.com';
7
+ var $theme_fields = array( 'Name','URI','Author','AuthorURI','Version' );
8
+ var $plugin_fields = array( 'Name','URI','Author','AuthorURI','Version','RequiresWP','RequiresPHP' );
9
+
10
+ public function __construct( $slug, $product_file, $action, $type ) {
11
+ $this->slug = $slug;
12
+ $this->type = $type;
13
+ $this->url = trailingslashit( $this->get_endpoint() . $action );
14
+
15
+ if ( 'plugin' == $type ) {
16
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
17
+ $plugin_data = get_plugin_data( $product_file );
18
+ $this->product_version = $plugin_data['Version'];
19
+ }
20
+ $this->do_action();
21
+ }
22
+
23
+ private function get_action() {
24
+ return $this->action;
25
+ }
26
+
27
+ private function get_slug() {
28
+ return $this->slug;
29
+ }
30
+
31
+ private function get_product_version() {
32
+ return $this->product_version;
33
+ }
34
+
35
+ private function get_module_type() {
36
+ return $this->type;
37
+ }
38
+
39
+ private function get_admin() {
40
+ return get_bloginfo( 'admin_email' );
41
+ }
42
+
43
+ private function get_endpoint() {
44
+ return trailingslashit( trailingslashit( $this->api_domain ) . 'api/v1/product/action' );
45
+ }
46
+
47
+ private function is_marketing_allowed() {
48
+ return 1;
49
+ }
50
+
51
+ private function is_deactivated() {
52
+ return false;
53
+ }
54
+
55
+ private function is_uninstall() {
56
+ return false;
57
+ }
58
+
59
+ private function get_uninstall_params() {
60
+ $reason_id = ''; $reason_info = '';
61
+ return array(
62
+ 'reason_id' => $reason_id,
63
+ 'reason_info' => $reason_info,
64
+ );
65
+ }
66
+
67
+ private function check_return_url() {
68
+ return admin_url();
69
+ }
70
+
71
+ private function check_site() {
72
+ return array(
73
+ 'wp_version' => get_bloginfo( 'version' ),
74
+ 'php_version' => phpversion(),
75
+ 'is_network' => ( ( is_multisite() ) ? 1 : 0 ),
76
+ 'site_url' => get_site_url(),
77
+ 'site_name' => get_bloginfo( 'name' ),
78
+ 'language' => get_bloginfo( 'language' ),
79
+ 'charset' => get_bloginfo( 'charset' ),
80
+ );
81
+ }
82
+
83
+ private function check_product() {
84
+
85
+ return array(
86
+ 'sdk_version' => $this->version,
87
+ 'license' => $this->check_license(),
88
+ 'slug' => $this->get_slug(),
89
+ 'version' => $this->get_product_version(),
90
+ 'is_active' => true,
91
+ 'is_uninstalled' => false,
92
+ );
93
+ }
94
+
95
+ private function check_addr() {
96
+ if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
97
+ $ip = $_SERVER['HTTP_CLIENT_IP'];
98
+ } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
99
+ $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
100
+ } else {
101
+ $ip = $_SERVER['REMOTE_ADDR'];
102
+ }
103
+ return $ip;
104
+ }
105
+
106
+ private function check_license() {
107
+ $license = get_option( $this->get_slug() . '-license', false );
108
+ return ( $license ) ? $license : false;
109
+ }
110
+
111
+ private function check_themes() {
112
+ $theme_data = wp_get_themes();
113
+ foreach ( $theme_data as $theme_slug => $theme ) {
114
+ $themes[ $theme_slug ] = array(
115
+ 'Name' => $theme->get( 'Name' ),
116
+ 'URI' => $theme->get( 'ThemeURI' ),
117
+ 'Author' => $theme->get( 'Author' ),
118
+ 'AuthorURI' => $theme->get( 'AuthorURI' ),
119
+ 'Version' => $theme->get( 'Version' ),
120
+ );
121
+ $themes[ $theme_slug ]['Active'] = ( $theme->get( 'Name' ) == wp_get_theme()->get('Name') ) ? 'active' : 'inactive';
122
+ }
123
+ return $themes;
124
+ }
125
+
126
+ private function check_plugins() {
127
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
128
+ $plugin_data = get_plugins();
129
+ $active_plugins = get_option( 'active_plugins' );
130
+ foreach ( $plugin_data as $plugin_slug => $plugin ) {
131
+ $plugins[ $plugin_slug ] = array(
132
+ 'Name' => $plugin['Name'],
133
+ 'URI' => $plugin['PluginURI'],
134
+ 'Author' => $plugin['Author'],
135
+ 'AuthorURI' => $plugin['AuthorURI'],
136
+ 'Version' => $plugin['Version'],
137
+ 'RequiresWP' => $plugin['RequiresWP'],
138
+ 'RequiresPHP' => $plugin['RequiresPHP'],
139
+ );
140
+ $plugins[ $plugin_slug ]['Active'] = ( in_array( $plugin_slug, $active_plugins ) ) ? 'active' : 'inactive';
141
+ }
142
+ return $plugins;
143
+ }
144
+ private function check_user() {
145
+ $user = wp_get_current_user();
146
+ $check_user = get_user_by( 'email', $this->get_admin() );
147
+ $admin = ( $check_user ) ? $check_user : false;
148
+ return array(
149
+ 'site' => array(
150
+ 'email' => ( $admin ) ? $admin->user_email : '',
151
+ 'first_name' => ( $admin ) ? $admin->first_name : '',
152
+ 'last_name' => ( $admin ) ? $admin->last_name : '',
153
+ ),
154
+ 'user' => array(
155
+ 'email' => $user->user_email,
156
+ 'first_name' => $user->first_name,
157
+ 'last_name' => $user->last_name,
158
+ ),
159
+ 'marketing' => $this->is_marketing_allowed(),
160
+ 'user_ip' => $this->check_addr(),
161
+ );
162
+ }
163
+
164
+ private function do_action() {
165
+
166
+ $params = array(
167
+ 'check_site' => $this->check_site(),
168
+ 'check_product' => $this->check_product(),
169
+ 'return_url' => $this->check_return_url(),
170
+ 'account_url' => admin_url(),
171
+ );
172
+
173
+ $params['check_user'] = $this->check_user();
174
+
175
+ if ( $this->is_uninstall() ) {
176
+ $params['uninstall_params'] = $this->get_uninstall_params();
177
+ }
178
+
179
+ $params['check_themes'] = $this->check_themes();
180
+ $params['check_plugins'] = $this->check_plugins();
181
+
182
+ $params['sdk_version'] = $this->version;
183
+ $params['format'] = 'json';
184
+
185
+ $request = array(
186
+ 'method' => 'POST',
187
+ 'body' => $params,
188
+ 'timeout' => 30,
189
+ );
190
+
191
+ $response = wp_remote_post( $this->url, $request );
192
+ if ( is_wp_error( $response ) ) {
193
+ /**
194
+ * @var WP_Error $response
195
+ */
196
+ $result = new stdClass();
197
+
198
+ $error_code = $response->get_error_code();
199
+ $error_type = str_replace( ' ', '', ucwords( str_replace( '_', ' ', $error_code ) ) );
200
+
201
+ $result->error = (object) array(
202
+ 'type' => $error_type,
203
+ 'message' => $response->get_error_message(),
204
+ 'code' => $error_code,
205
+ 'http' => 402
206
+ );
207
+
208
+ $this->maybe_modify_api_curl_error_message( $result );
209
+
210
+ return $result;
211
+ }
212
+
213
+ // Module is being uninstalled, don't handle the returned data.
214
+ if ( $this->is_uninstall() ) {
215
+ return true;
216
+ }
217
+
218
+ }
219
+
220
+ /**
221
+ * Handles cURL error message.
222
+ *
223
+ * @since 1.0.0
224
+ *
225
+ * @param object $result
226
+ */
227
+ private function maybe_modify_api_curl_error_message( $result ) {
228
+ if ( 'cUrlMissing' !== $result->error->type &&
229
+ ( 'CurlException' !== $result->error->type || CURLE_COULDNT_CONNECT != $result->error->code ) &&
230
+ ( 'HttpRequestFailed' !== $result->error->type || false === strpos( $result->error->message, 'cURL error ' . CURLE_COULDNT_CONNECT ) )
231
+ ) {
232
+ return;
233
+ }
234
+
235
+ $result->error->message = esc_html(
236
+ __( 'We use PHP cURL library for the API calls, which is a very common library and usually installed and activated out of the box. Unfortunately, cURL is not activated (or disabled) on your server.', 'text-domain' ) .
237
+ ' ' .
238
+ sprintf(
239
+ __( 'Please contact your hosting provider and ask them to whitelist %s for external connection.', 'text-domain' ),
240
+ implode(
241
+ ', ',
242
+ apply_filters( 'api_domains', array(
243
+ 'rocketgeek.com',
244
+ ) )
245
+ )
246
+ ) .
247
+ ' ' .
248
+ sprintf( __( 'Once you are done, deactivate the %s and activate it again.', 'text-domain' ), $this->get_module_type() )
249
+ );
250
+ }
251
+ }
252
+ endif;
includes/vendor/rocketgeek-utilities/includes/forms.php CHANGED
@@ -122,15 +122,17 @@ if ( ! function_exists( 'rktgk_sanitize_field' ) ):
122
  * handled and validated.
123
  *
124
  * @since 1.0.0
 
125
  *
126
  * @param string $data
127
- * @param string $type (multiselect|multicheckbox|textarea|email|file|image|int|integer|number)
128
  * @return string $sanitized_data
129
  */
130
  function rktgk_sanitize_field( $data, $type = '' ) {
131
 
132
  switch ( $type ) {
133
 
 
134
  case 'multiselect':
135
  case 'multicheckbox':
136
  case 'multipleselect':
@@ -156,7 +158,16 @@ function rktgk_sanitize_field( $data, $type = '' ) {
156
  case 'number':
157
  $sanitized_data = intval( $data );
158
  break;
 
 
 
 
 
 
 
 
159
 
 
160
  default:
161
  $sanitized_data = sanitize_text_field( $data );
162
  break;
122
  * handled and validated.
123
  *
124
  * @since 1.0.0
125
+ * @since 1.0.1 Added text, url, array, class as accepted $type
126
  *
127
  * @param string $data
128
+ * @param string $type (text|array|multiselect|multicheckbox|textarea|email|file|image|int|integer|number|url|class) Default:text
129
  * @return string $sanitized_data
130
  */
131
  function rktgk_sanitize_field( $data, $type = '' ) {
132
 
133
  switch ( $type ) {
134
 
135
+ case 'array':
136
  case 'multiselect':
137
  case 'multicheckbox':
138
  case 'multipleselect':
158
  case 'number':
159
  $sanitized_data = intval( $data );
160
  break;
161
+
162
+ case 'url':
163
+ $sanitized_data = sanitize_url( $data );
164
+ break;
165
+
166
+ case 'class':
167
+ $sanitized_data = rktgk_sanitize_class( $data );
168
+ break;
169
 
170
+ case 'text':
171
  default:
172
  $sanitized_data = sanitize_text_field( $data );
173
  break;
includes/vendor/rocketgeek-utilities/loader.php CHANGED
@@ -9,7 +9,7 @@
9
  * useful for your project(s). Attribution is appreciated ;-)
10
  *
11
  * @package RocketGeek_Utilities
12
- * @version 1.0.0
13
  *
14
  * @link https://github.com/rocketgeek/rocketgeek-utilities/
15
  * @author Chad Butler <https://butlerblog.com>
9
  * useful for your project(s). Attribution is appreciated ;-)
10
  *
11
  * @package RocketGeek_Utilities
12
+ * @version 1.0.1
13
  *
14
  * @link https://github.com/rocketgeek/rocketgeek-utilities/
15
  * @author Chad Butler <https://butlerblog.com>
readme.txt CHANGED
@@ -2,16 +2,14 @@
2
  Contributors: cbutlerjr
3
  Tags: access, authentication, content, login, member, membership, password, protect, register, registration, restriction, subscriber
4
  Requires at least: 4.0
5
- Tested up to: 5.9
6
- Stable tag: 3.4.1.2
7
 
8
  License: GPLv3
9
 
10
  == Description ==
11
 
12
- The original membership plugin for WordPress, WP-Members turns WordPress into a membership site. Content restriction, custom registration, and more.
13
-
14
- WP-Members was the first WordPress membership plugin, and it continues in active development to keep pace with what's new and current in WordPress. The plugin's original idea is still it's most important: keep it simple to setup and configure, but provide standard hooks to allow it to be customized as needed.
15
 
16
  === Membership Sites. Simplified. ===
17
 
@@ -110,7 +108,7 @@ The FAQs are maintained at https://rocketgeek.com/plugins/wp-members/docs/faqs/
110
 
111
  == Upgrade Notice ==
112
 
113
- WP-Members 3.4.1 is a minor update. Backup prior to upgrading is recommended. See changelog for important details. Minimum WP version is 4.0.
114
 
115
 
116
  == Screenshots ==
@@ -134,18 +132,37 @@ WP-Members 3.4.1 is a minor update. Backup prior to upgrading is recommended. Se
134
 
135
  == Changelog ==
136
 
137
- = 3.4.1.2 =
 
 
 
 
 
 
 
 
138
 
139
  * Applies checkbox CSS in add new user form.
140
  * Code consolidation in admin options tab file (remove final use of wpmem_use_ssl()).
141
  * Add wpmem_recaptcha_url filter to allow for changing the URL of the recaptcha script.
142
  * Only apply pwd reset override on frontend (for login error).
143
  * Fixes undefined $wpmem->reg_form_showing.
144
-
145
- = 3.4.1.1 =
146
-
147
  * Fixes a bug in the password change shortcode that causes a "too few arguments" error.
148
  * Changes wpmem_is_user_current() to wpmem_user_is_current() for backwards compatibility with the plugin's premium PayPal extension.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
  = 3.4.1 =
151
 
2
  Contributors: cbutlerjr
3
  Tags: access, authentication, content, login, member, membership, password, protect, register, registration, restriction, subscriber
4
  Requires at least: 4.0
5
+ Tested up to: 6.0
6
+ Stable tag: 3.4.2
7
 
8
  License: GPLv3
9
 
10
  == Description ==
11
 
12
+ The original membership plugin with content restriction, custom registration, and more.
 
 
13
 
14
  === Membership Sites. Simplified. ===
15
 
108
 
109
  == Upgrade Notice ==
110
 
111
+ WP-Members 3.4.2 is a minor update. WP-Members 3.4.2.1 is a bug fix release. Backup prior to upgrading is recommended, but rollback is possible. See changelog for a list of updates. Minimum WP version is 4.0.
112
 
113
 
114
  == Screenshots ==
132
 
133
  == Changelog ==
134
 
135
+ = 3.5.0 =
136
+
137
+ * @todo WP-Members pluggable deprecated for use in theme functions.php (wpmem will be initialized when plugins are loaded). If you have any WP-Members pluggable functions that load in the theme functions.php, you'll need to move these to another location, such as a custom plugin file. Keep in mind, pluggable functions are no longer the preferred way of customizing (and have not been for many years) as most customizations, if not all, can be handled by using the plugin's filter and action hooks.
138
+
139
+ = 3.4.2.1 =
140
+
141
+ * Bug fix in the onboarding notification that causes form conflicts if the install/upgrade process is not finalized.
142
+
143
+ = 3.4.2 =
144
 
145
  * Applies checkbox CSS in add new user form.
146
  * Code consolidation in admin options tab file (remove final use of wpmem_use_ssl()).
147
  * Add wpmem_recaptcha_url filter to allow for changing the URL of the recaptcha script.
148
  * Only apply pwd reset override on frontend (for login error).
149
  * Fixes undefined $wpmem->reg_form_showing.
 
 
 
150
  * Fixes a bug in the password change shortcode that causes a "too few arguments" error.
151
  * Changes wpmem_is_user_current() to wpmem_user_is_current() for backwards compatibility with the plugin's premium PayPal extension.
152
+ * Added the action being done as a parameter passed to the wpmem_get_action action hook.
153
+ * Added support for arrays, urls, and classes to wpmem_sanitize_field() (alias of rktgk_sanitize_field()). This is in addition to the sanitization already supported.
154
+ * apply_custom_product_message() now runs do_shortcode() to natively support shortcodes in custom membership product messages.
155
+ * Fixed an issue that did not display the custom product message if the user was not logged in.
156
+ * Improved custom product message for non-logged in state (same function is used by both logged in and logged out processes, so cleaned up to handle both states the same).
157
+ * Bug fix in password reset that potentially truncates the reset link.
158
+ * Bug fix in admin notification email for HTML formatted email (wpautop() was not being applied to email content).
159
+ * Bug fix in wpmem_is_reg_type() that returned invalid object var.
160
+ * Added email arg for default linebreak.
161
+ * Added user ID to email filters.
162
+ * Added id, class, and wrapper attributes to [wpmem_logged_in] shortcode (wrapper defaults to "div" but can be changed to "span" or "p" or something else).
163
+ * Added user confirmed field to default export fields (if confirmation link setting is enabled).
164
+ * Added wpmem_set_user_membership(), wpmem_remove_user_membership(), and wpmem_get_user_memberships() API functions.
165
+ * Introduces new installer/onboarding for both new installs and upgrades.
166
 
167
  = 3.4.1 =
168
 
uninstall.php CHANGED
@@ -61,6 +61,7 @@ function wpmem_uninstall_options() {
61
  delete_option( 'wpmembers_utfields' );
62
  delete_option( 'wpmembers_usfields' );
63
  delete_option( 'wpmembers_dropins' );
 
64
 
65
  delete_option( 'wpmembers_email_newreg' );
66
  delete_option( 'wpmembers_email_newmod' );
@@ -83,10 +84,21 @@ function wpmem_uninstall_options() {
83
  delete_option( 'wpmembers_style' );
84
  delete_option( 'wpmembers_autoex' );
85
  delete_option( 'wpmembers_attrib' );
 
 
 
 
86
 
87
  // Drop user meta key search table.
88
  global $wpdb;
89
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpmembers_user_search_keys" );
 
 
 
 
 
 
 
90
  }
91
 
92
  // End of file.
61
  delete_option( 'wpmembers_utfields' );
62
  delete_option( 'wpmembers_usfields' );
63
  delete_option( 'wpmembers_dropins' );
64
+ delete_option( 'wpmem_hidden_posts' );
65
 
66
  delete_option( 'wpmembers_email_newreg' );
67
  delete_option( 'wpmembers_email_newmod' );
84
  delete_option( 'wpmembers_style' );
85
  delete_option( 'wpmembers_autoex' );
86
  delete_option( 'wpmembers_attrib' );
87
+
88
+ delete_option( 'wpmembers_install_state' );
89
+
90
+ delete_transient( 'wpmem_user_counts' );
91
 
92
  // Drop user meta key search table.
93
  global $wpdb;
94
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpmembers_user_search_keys" );
95
+
96
+ $optin = get_option( 'wpmembers_optin' );
97
+ if ( 1 == $optin ) {
98
+ include_once( plugin_dir_path( __FILE__ ) . 'includes/vendor/rocketgeek-tools/class-rocketgeek-satellite.php' );
99
+ $uninstall = new RocketGeek_Satellite_Beta( 'wp-members', plugin_dir_path( __FILE__ ) . 'wp-members.php', 'delete', 'plugin' );
100
+ }
101
+ delete_option( 'wpmembers_optin' );
102
  }
103
 
104
  // End of file.
wp-members.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP-Members
4
  Plugin URI: https://rocketgeek.com
5
  Description: WP access restriction and user registration. For more information on plugin features, refer to <a href="https://rocketgeek.com/plugins/wp-members/docs/">the online Users Guide</a>. A <a href="https://rocketgeek.com/plugins/wp-members/quick-start-guide/">Quick Start Guide</a> is also available. WP-Members(tm) is a trademark of butlerblog.com.
6
- Version: 3.4.1.2
7
  Author: Chad Butler
8
  Author URI: https://butlerblog.com/
9
  Text Domain: wp-members
@@ -58,7 +58,7 @@ if ( ! defined( 'ABSPATH' ) ) {
58
  }
59
 
60
  // Initialize constants.
61
- define( 'WPMEM_VERSION', '3.4.1.2' );
62
  define( 'WPMEM_DB_VERSION', '2.3.0' );
63
  define( 'WPMEM_PATH', plugin_dir_path( __FILE__ ) );
64
 
@@ -68,8 +68,8 @@ add_action( 'after_setup_theme', 'wpmem_init', 10 );
68
  // Install the plugin.
69
  register_activation_hook( __FILE__, 'wpmem_install' );
70
 
71
- // Downgrade settings on deactivation.
72
- //register_deactivation_hook( __FILE__, 'wpmem_downgrade' );
73
 
74
 
75
  /**
@@ -177,8 +177,9 @@ function wpmem_install() {
177
  *
178
  * @since 3.1.1
179
  */
180
- function wpmem_downgrade() {
181
- //wpmem_install( 'downgrade' );
 
182
  }
183
 
184
 
3
  Plugin Name: WP-Members
4
  Plugin URI: https://rocketgeek.com
5
  Description: WP access restriction and user registration. For more information on plugin features, refer to <a href="https://rocketgeek.com/plugins/wp-members/docs/">the online Users Guide</a>. A <a href="https://rocketgeek.com/plugins/wp-members/quick-start-guide/">Quick Start Guide</a> is also available. WP-Members(tm) is a trademark of butlerblog.com.
6
+ Version: 3.4.2.1
7
  Author: Chad Butler
8
  Author URI: https://butlerblog.com/
9
  Text Domain: wp-members
58
  }
59
 
60
  // Initialize constants.
61
+ define( 'WPMEM_VERSION', '3.4.2.1' );
62
  define( 'WPMEM_DB_VERSION', '2.3.0' );
63
  define( 'WPMEM_PATH', plugin_dir_path( __FILE__ ) );
64
 
68
  // Install the plugin.
69
  register_activation_hook( __FILE__, 'wpmem_install' );
70
 
71
+ // Run deactivation.
72
+ register_deactivation_hook( __FILE__, 'wpmem_deactivate' );
73
 
74
 
75
  /**
177
  *
178
  * @since 3.1.1
179
  */
180
+ function wpmem_deactivate() {
181
+ include_once( 'includes/install.php' );
182
+ wpmem_plugin_deactivate();
183
  }
184
 
185