WP-Members Membership Plugin - Version 3.2.6

Version Description

  • Added nonce to short form (long form was added in 3.2.5).
  • Password change function only can be fired if user is logged in.
  • Added "all" argument to wpmem_user_data() to retrieve either all user meta or WP-Members fields only.
  • Added $date argument to wpmem_set_user_product(). Allows specific date to be set using API.
  • Added wpmem_admin_after_profile_table and wpmem_user_after_profile_table actions.
  • get_user_products() returns empty array if no products (previously boolean).
  • Rebuild of [wpmem_field] logic for field type. Combined multiple conditions into a single switch.
  • Update password reset form - password field should be "text" class.
  • Added membership field type for allowing selection of a membership at registration.
  • Login form updated from "Username" to "Username or Email".
  • Added $arr parameter to wpmem_login_form_rows filter.
  • Added file's post ID to post_data array.
  • Update to evaluate required fields as not null (instead of false).
  • Added wpmem_tos_link_tag filter.
  • Added $button_html parameter to wpmem_register_form_buttons filter.
  • Added wpmem_serve_menu filter.
  • Fixed display issue with password shortcode which caused message dialog to display in default state.
  • Fixed console error with short form nonce.
Download this release

Release Info

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

Code changes from version 3.2.5 to 3.2.6

admin/includes/class-wp-members-user-search.php CHANGED
@@ -38,6 +38,15 @@ class WP_Members_Admin_User_Search {
38
  * @var array
39
  */
40
  public $keys = array();
 
 
 
 
 
 
 
 
 
41
 
42
  /**
43
  * Constructor function.
@@ -94,13 +103,13 @@ class WP_Members_Admin_User_Search {
94
  }
95
 
96
  // Use a permanent table because you cannot reference MySQL temporary tables more than once per query.
97
- $mktable = "{$wpdb->prefix}wpmembers_user_search_keys";
98
 
99
- // Create the table to store the meta keys.
100
- $wpdb->query( $sql = "CREATE TABLE IF NOT EXISTS {$mktable} (meta_key VARCHAR(255) NOT NULL);" );
101
 
102
  // Empty the table to ensure that we have an accurate set of meta keys.
103
- $wpdb->query( $sql = "TRUNCATE TABLE {$mktable};" );
104
 
105
  // Insert the meta keys into the table.
106
  $prepare_values_array = array_fill( 0, count( $meta_keys ), '(%s)' );
38
  * @var array
39
  */
40
  public $keys = array();
41
+
42
+ /**
43
+ * Table name.
44
+ *
45
+ * @since 3.2.6
46
+ * @access private
47
+ * @var string
48
+ */
49
+ private $table = "wpmembers_user_search_keys";
50
 
51
  /**
52
  * Constructor function.
103
  }
104
 
105
  // Use a permanent table because you cannot reference MySQL temporary tables more than once per query.
106
+ $mktable = $wpdb->prefix . $this->table;
107
 
108
+ // If the table does not exist, create the table to store the meta keys.
109
+ $wpdb->query( "CREATE TABLE IF NOT EXISTS {$mktable} (meta_key VARCHAR(255) NOT NULL);" );
110
 
111
  // Empty the table to ensure that we have an accurate set of meta keys.
112
+ $wpdb->query( "TRUNCATE TABLE {$mktable};" );
113
 
114
  // Insert the meta keys into the table.
115
  $prepare_values_array = array_fill( 0, count( $meta_keys ), '(%s)' );
admin/tab-fields.php CHANGED
@@ -223,6 +223,9 @@ function wpmem_a_render_fields_tab_field_edit( $mode, $wpmem_fields, $meta_key )
223
  <option value="number"><?php _e( 'number', 'wp-members' ); ?></option>
224
  <option value="date"><?php _e( 'date', 'wp-members' ); ?></option>
225
  <option value="hidden"><?php _e( 'hidden', 'wp-members' ); ?></option>
 
 
 
226
  </select>
227
  <?php } ?>
228
  </li>
223
  <option value="number"><?php _e( 'number', 'wp-members' ); ?></option>
224
  <option value="date"><?php _e( 'date', 'wp-members' ); ?></option>
225
  <option value="hidden"><?php _e( 'hidden', 'wp-members' ); ?></option>
226
+ <?php if ( $wpmem->enable_products ) { ?>
227
+ <option value="membership"><?php _e( 'membership', 'wp-members' ); ?></option>
228
+ <?php } ?>
229
  </select>
230
  <?php } ?>
231
  </li>
inc/api-users.php CHANGED
@@ -118,11 +118,12 @@ function wpmem_is_user_activated( $user_id = false ) {
118
  *
119
  * @global object $wpmem
120
  * @param integer $user_id
 
121
  * @return array $user_fields
122
  */
123
- function wpmem_user_data( $user_id = false ) {
124
  global $wpmem;
125
- return $wpmem->user_fields( $user_id );
126
  }
127
 
128
  /**
@@ -163,15 +164,17 @@ function wpmem_user_has_access( $product, $user_id = false ) {
163
  * Sets product access for a user.
164
  *
165
  * @since 3.2.3
 
166
  *
167
  * @global object $wpmem
168
  * @param string $product The meta key of the product.
169
  * @param int $user_id
 
170
  * @return bool $result
171
  */
172
- function wpmem_set_user_product( $product, $user_id = false ) {
173
  global $wpmem;
174
- return $wpmem->user->set_user_product( $product, $user_id );
175
  }
176
 
177
  /**
118
  *
119
  * @global object $wpmem
120
  * @param integer $user_id
121
+ * @param bool $all
122
  * @return array $user_fields
123
  */
124
+ function wpmem_user_data( $user_id = false, $all = false ) {
125
  global $wpmem;
126
+ return $wpmem->user->user_data( $user_id, $all );
127
  }
128
 
129
  /**
164
  * Sets product access for a user.
165
  *
166
  * @since 3.2.3
167
+ * @since 3.2.6 Added $date to set a specific expiration date.
168
  *
169
  * @global object $wpmem
170
  * @param string $product The meta key of the product.
171
  * @param int $user_id
172
+ * @param string $date Expiration date (optional) format: MySQL timestamp
173
  * @return bool $result
174
  */
175
+ function wpmem_set_user_product( $product, $user_id = false, $date = false ) {
176
  global $wpmem;
177
+ return $wpmem->user->set_user_product( $product, $user_id, $date );
178
  }
179
 
180
  /**
inc/api-utilities.php CHANGED
@@ -258,6 +258,8 @@ function wpmem_format_date( $args ) {
258
  * @author J.D. Grimes
259
  * @link https://codesymphony.co/dont-do_shortcode/
260
  *
 
 
261
  * @param string $tag The shortcode whose function to call.
262
  * @param array $atts The attributes to pass to the shortcode function. Optional.
263
  * @param array $content The shortcode's content. Default is null (none).
258
  * @author J.D. Grimes
259
  * @link https://codesymphony.co/dont-do_shortcode/
260
  *
261
+ * @since 3.2.5
262
+ *
263
  * @param string $tag The shortcode whose function to call.
264
  * @param array $atts The attributes to pass to the shortcode function. Optional.
265
  * @param array $content The shortcode's content. Default is null (none).
inc/class-wp-members-forms.php CHANGED
@@ -1,1590 +1,1628 @@
1
- <?php
2
- /**
3
- * The WP_Members Forms Class.
4
- *
5
- * @package WP-Members
6
- * @subpackage WP_Members Forms Object Class
7
- * @since 3.1.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit();
13
- }
14
-
15
- class WP_Members_Forms {
16
-
17
- /**
18
- * Plugin initialization function.
19
- *
20
- * @since 3.1.0
21
- */
22
- function __construct() {
23
-
24
- }
25
-
26
- /**
27
- * Creates form fields
28
- *
29
- * Creates various form fields and returns them as a string.
30
- *
31
- * @since 3.1.0
32
- * @since 3.1.1 Added $delimiter.
33
- * @since 3.1.2 Changed $valtochk to $compare.
34
- * @since 3.1.6 Added $placeholder.
35
- * @since 3.1.7 Added number type & $min, $max, $title and $pattern attributes.
36
- * @since 3.2.0 Added $id argument.
37
- * @since 3.2.4 Added radio group and multiple checkbox individual item labels.
38
- *
39
- * @param array $args {
40
- * @type string $id
41
- * @type string $name
42
- * @type string $type
43
- * @type string $value
44
- * @type string $compare
45
- * @type string $class
46
- * @type boolean $required
47
- * @type string $delimiter
48
- * @type string $placeholder
49
- * @type string $pattern
50
- * @type string $title
51
- * @type string $min
52
- * @type string $max
53
- * @type string $rows Number of rows for a textarea (default:5).
54
- * @type string $cols Number of columns for a textarea (default:20).
55
- * }
56
- * @return string $str The field returned as a string.
57
- */
58
- function create_form_field( $args ) {
59
-
60
- $id = ( isset( $args['id'] ) ) ? esc_attr( $args['id'] ) : esc_attr( $args['name'] );
61
- $name = esc_attr( $args['name'] );
62
- $type = esc_attr( $args['type'] );
63
- $value = ( isset( $args['value'] ) ) ? maybe_unserialize( $args['value'] ) : '';
64
- $compare = ( isset( $args['compare'] ) ) ? $args['compare'] : '';
65
- $class = ( isset( $args['class'] ) ) ? $args['class'] : 'textbox';
66
- $required = ( isset( $args['required'] ) ) ? $args['required'] : false;
67
- $delimiter = ( isset( $args['delimiter'] ) ) ? $args['delimiter'] : '|';
68
- $placeholder = ( isset( $args['placeholder'] ) ) ? $args['placeholder'] : false;
69
- $pattern = ( isset( $args['pattern'] ) ) ? $args['pattern'] : false;
70
- $title = ( isset( $args['title'] ) ) ? $args['title'] : false;
71
-
72
- switch ( $type ) {
73
-
74
- case "text":
75
- case "url":
76
- case "email":
77
- case "number":
78
- case "date":
79
- $class = ( 'textbox' == $class ) ? "textbox" : $this->sanitize_class( $class );
80
- switch ( $type ) {
81
- case 'url':
82
- $value = esc_url( $value );
83
- break;
84
- case 'email':
85
- $value = esc_attr( wp_unslash( $value ) );
86
- break;
87
- //case 'number':
88
- //$value = esc_attr( $value );
89
- default:
90
- $value = stripslashes( esc_attr( $value ) );
91
- break;
92
- }
93
- $required = ( $required ) ? ' required' : '';
94
- $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
95
- $pattern = ( $pattern ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
96
- $title = ( $title ) ? ' title="' . esc_attr( $title ) . '"' : '';
97
- $min = ( isset( $args['min'] ) && $args['min'] != '' ) ? ' min="' . esc_attr( $args['min'] ) . '"' : '';
98
- $max = ( isset( $args['max'] ) && $args['max'] != '' ) ? ' max="' . esc_attr( $args['max'] ). '"' : '';
99
- $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"$value\" class=\"$class\"$placeholder$title$pattern$min$max" . ( ( $required ) ? " required " : "" ) . " />";
100
- break;
101
-
102
- case "password":
103
- $class = $this->sanitize_class( $class );
104
- $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
105
- $pattern = ( $pattern ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
106
- $title = ( $title ) ? ' title="' . esc_attr( $title ) . '"' : '';
107
- $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" class=\"$class\"$placeholder$title$pattern" . ( ( $required ) ? " required " : "" ) . " />";
108
- break;
109
-
110
- case "image":
111
- case "file":
112
- $class = ( 'textbox' == $class ) ? "file" : $this->sanitize_class( $class );
113
- $str = "<input name=\"$name\" type=\"file\" id=\"$id\" value=\"$value\" class=\"$class\"" . ( ( $required ) ? " required " : "" ) . " />";
114
- break;
115
-
116
- case "checkbox":
117
- $class = ( 'textbox' == $class ) ? "checkbox" : $this->sanitize_class( $class );
118
- $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"" . esc_attr( $value ) . "\"" . checked( $value, $compare, false ) . ( ( $required ) ? " required " : "" ) . " />";
119
- break;
120
-
121
- case "textarea":
122
- $value = esc_textarea( stripslashes( $value ) ); // stripslashes( esc_textarea( $value ) );
123
- $class = ( 'textbox' == $class ) ? "textarea" : $this->sanitize_class( $class );
124
- $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
125
- $rows = ( isset( $args['rows'] ) && $args['rows'] ) ? esc_attr( $args['rows'] ) : '5';
126
- $cols = ( isset( $args['cols'] ) && $args['cols'] ) ? esc_attr( $args['cols'] ) : '20';
127
- $str = "<textarea cols=\"$cols\" rows=\"$rows\" name=\"$name\" id=\"$id\" class=\"$class\"$placeholder" . ( ( $required ) ? " required " : "" ) . ">$value</textarea>";
128
- break;
129
-
130
- case "hidden":
131
- $str = "<input name=\"$name\" type=\"$type\" value=\"" . esc_attr( $value ) . "\" />";
132
- break;
133
-
134
- case "option":
135
- $str = "<option value=\"" . esc_attr( $value ) . "\" " . selected( $value, $compare, false ) . " >$name</option>";
136
- break;
137
-
138
- case "select":
139
- case "multiselect":
140
- $class = ( 'textbox' == $class && 'multiselect' != $type ) ? "dropdown" : $class;
141
- $class = ( 'textbox' == $class && 'multiselect' == $type ) ? "multiselect" : $class;
142
- $pname = ( 'multiselect' == $type ) ? $name . "[]" : $name;
143
- $str = "<select name=\"$pname\" id=\"$id\" class=\"$class\"" . ( ( 'multiselect' == $type ) ? " multiple " : "" ) . ( ( $required ) ? " required " : "" ) . ">\n";
144
- foreach ( $value as $option ) {
145
- $pieces = explode( '|', $option );
146
- if ( 'multiselect' == $type ) {
147
- $chk = '';
148
- $values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
149
- } else {
150
- $chk = $compare;
151
- $values = array();
152
- }
153
- if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
154
- $chk = ( ( isset( $pieces[2] ) && '' == $compare ) || in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk;
155
- } else {
156
- $chk = 'not selected';
157
- }
158
- $str = $str . "<option value=\"$pieces[1]\"" . selected( $pieces[1], $chk, false ) . ">" . __( $pieces[0], 'wp-members' ) . "</option>\n";
159
- }
160
- $str = $str . "</select>";
161
- break;
162
-
163
- case "multicheckbox":
164
- $class = ( 'textbox' == $class ) ? "checkbox" : $class;
165
- $str = '';
166
- $num = 1;
167
- foreach ( $value as $option ) {
168
- $pieces = explode( '|', $option );
169
- $values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
170
- $chk = ( isset( $pieces[2] ) && '' == $compare ) ? $pieces[1] : '';
171
- if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
172
- $id_value = esc_attr( $id . '[' . $pieces[1] . ']' );
173
- $label = wpmem_form_label( array( 'meta_key'=>$id_value, 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'radio', 'id'=>$id_value ) );
174
- $str = $str . $this->create_form_field( array(
175
- 'id' => $id_value,
176
- 'name' => $name . '[]',
177
- 'type' => 'checkbox',
178
- 'value' => $pieces[1],
179
- 'compare' => ( in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk,
180
- ) ) . "&nbsp;" . $label . "<br />\n";
181
- } else {
182
- $str = $str . '<span class="div_multicheckbox_separator">' . esc_html( $pieces[0] ) . "</span><br />\n";
183
- }
184
- }
185
- break;
186
-
187
- case "radio":
188
- $class = ( 'textbox' == $class ) ? "radio" : $this->sanitize_class( $class );
189
- $str = '';
190
- $num = 1;
191
- foreach ( $value as $option ) {
192
- $pieces = explode( '|', $option );
193
- $id_num = $id . '_' . $num;
194
- if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
195
- $label = wpmem_form_label( array( 'meta_key'=>esc_attr( $id_num ), 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'radio', 'id'=>esc_attr( "label_" . $id_num ) ) );
196
- $str = $str . "<input type=\"radio\" name=\"$name\" id=\"" . esc_attr( $id_num ) . "\" value=\"" . esc_attr( $pieces[1] ) . '"' . checked( $pieces[1], $compare, false ) . ( ( $required ) ? " required " : " " ) . "> $label<br />\n";
197
- $num++;
198
- } else {
199
- $str = $str . '<span class="div_radio_separator">' . esc_html( __( $pieces[0], 'wp-members' ) ) . "</span><br />\n";
200
- }
201
- }
202
- break;
203
-
204
- }
205
-
206
- return $str;
207
- } // End create_form_field()
208
-
209
- /**
210
- * Create form label.
211
- *
212
- * @since 3.1.7
213
- * @since 3.2.4 Added $id
214
- *
215
- * @param array $args {
216
- * @type string $meta_key
217
- * @type string $label
218
- * @type string $type
219
- * @type string $id (optional)
220
- * @type string $class (optional)
221
- * @type string $required (optional)
222
- * @type string $req_mark (optional)
223
- * }
224
- * @return string $label
225
- */
226
- function create_form_label( $args ) {
227
- global $wpmem;
228
-
229
- $meta_key = $args['meta_key'];
230
- $label = $args['label'];
231
- $type = $args['type'];
232
- $class = ( isset( $args['class'] ) ) ? $args['class'] : false;
233
- $id = ( isset( $args['id'] ) ) ? $args['id'] : false;
234
- $required = ( isset( $args['required'] ) ) ? $args['required'] : false;
235
- $req_mark = ( isset( $args['req_mark'] ) ) ? $args['req_mark'] : false;
236
-
237
- //$req_mark = ( ! $req_mark ) ? $wpmem->get_text( 'register_req_mark' ) : '*';
238
-
239
- if ( ! $class ) {
240
- $class = ( $type == 'password' || $type == 'email' || $type == 'url' ) ? 'text' : $type;
241
- }
242
-
243
- $id = ( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
244
-
245
- $label = '<label for="' . esc_attr( $meta_key ) . '"' . $id . ' class="' . $this->sanitize_class( $class ) . '">' . __( $label, 'wp-members' );
246
- $label = ( $required ) ? $label . $req_mark : $label;
247
- $label = $label . '</label>';
248
-
249
- return $label;
250
- }
251
-
252
- /**
253
- * Sanitizes classes passed to the WP-Members form building functions.
254
- *
255
- * This generally uses just sanitize_html_class() but allows for
256
- * whitespace so multiple classes can be passed (such as "regular-text code").
257
- *
258
- * @since 3.2.0
259
- *
260
- * @param string $class
261
- * @return string sanitized_class
262
- */
263
- function sanitize_class( $class ) {
264
- // If no whitespace, just return WP sanitized class.
265
- if ( ! strpos( $class, ' ' ) ) {
266
- return sanitize_html_class( $class );
267
- } else {
268
- // Break string by whitespace, sanitize individual class names.
269
- $class_array = explode( ' ', $class );
270
- $len = count( $class_array ); $i = 0;
271
- $sanitized_class = '';
272
- foreach ( $class_array as $single_class ) {
273
- $sanitized_class .= sanitize_html_class( $single_class );
274
- $sanitized_class .= ( $i == $len - 1 ) ? '' : ' ';
275
- $i++;
276
- }
277
- return $sanitized_class;
278
- }
279
- }
280
- /**
281
- * Uploads file from the user.
282
- *
283
- * @since 3.1.0
284
- *
285
- * @param array $file
286
- * @param int $user_id
287
- * @return int|bool
288
- */
289
- function do_file_upload( $file = array(), $user_id = false ) {
290
-
291
- // Filter the upload directory.
292
- add_filter( 'upload_dir', array( &$this,'file_upload_dir' ) );
293
-
294
- // Set up user ID for use in upload process.
295
- $this->file_user_id = ( $user_id ) ? $user_id : 0;
296
-
297
- // Get WordPress file upload processing scripts.
298
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
299
-
300
- $file_return = wp_handle_upload( $file, array( 'test_form' => false ) );
301
-
302
- if ( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
303
- return false;
304
- } else {
305
-
306
- $attachment = array(
307
- 'post_mime_type' => $file_return['type'],
308
- 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_return['file'] ) ),
309
- 'post_content' => '',
310
- 'post_status' => 'inherit',
311
- 'guid' => $file_return['url'],
312
- 'post_author' => ( $user_id ) ? $user_id : '',
313
- );
314
-
315
- $attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
316
-
317
- require_once( ABSPATH . 'wp-admin/includes/image.php' );
318
- $attachment_data = wp_generate_attachment_metadata( $attachment_id, $file_return['file'] );
319
- wp_update_attachment_metadata( $attachment_id, $attachment_data );
320
-
321
- if ( 0 < intval( $attachment_id ) ) {
322
- // Returns an array with file information.
323
- return $attachment_id;
324
- }
325
- }
326
-
327
- return false;
328
- } // End upload_file()
329
-
330
- /**
331
- * Sets the file upload directory.
332
- *
333
- * This is a filter function for upload_dir.
334
- *
335
- * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/upload_dir
336
- *
337
- * @since 3.1.0
338
- *
339
- * @param array $param {
340
- * The directory information for upload.
341
- *
342
- * @type string $path
343
- * @type string $url
344
- * @type string $subdir
345
- * @type string $basedir
346
- * @type string $baseurl
347
- * @type string $error
348
- * }
349
- * @return array $param
350
- */
351
- function file_upload_dir( $param ) {
352
- $user_id = ( isset( $this->file_user_id ) ) ? $this->file_user_id : null;
353
-
354
- $args = array(
355
- 'user_id' => $user_id,
356
- 'wpmem_dir' => 'wpmembers/',
357
- 'user_dir' => 'user_files/' . $user_id,
358
- );
359
- /**
360
- * Filter the user directory elements.
361
- *
362
- * @since 3.1.0
363
- *
364
- * @param array $args
365
- */
366
- $args = apply_filters( 'wpmem_user_upload_dir', $args );
367
-
368
- $param['subdir'] = '/' . $args['wpmem_dir'] . $args['user_dir'];
369
- $param['path'] = $param['basedir'] . '/' . $args['wpmem_dir'] . $args['user_dir'];
370
- $param['url'] = $param['baseurl'] . '/' . $args['wpmem_dir'] . $args['user_dir'];
371
-
372
- return $param;
373
- }
374
-
375
- /**
376
- * Login Form Builder.
377
- *
378
- * Builds the form used for login, change password, and reset password.
379
- *
380
- * @since 2.5.1
381
- * @since 3.1.7 Moved to forms object class as login_form().
382
- * @since 3.1.7 Added WP action login_form.
383
- *
384
- * @param string $page
385
- * @param array $arr {
386
- * The elements needed to generate the form (login|reset password|forgotten password).
387
- *
388
- * @type string $heading Form heading text.
389
- * @type string $action The form action (login|pwdchange|pwdreset|getusername).
390
- * @type string $button_text Form submit button text.
391
- * @type array $inputs {
392
- * The form input values.
393
- *
394
- * @type array {
395
- *
396
- * @type string $name The field label.
397
- * @type string $type Input type.
398
- * @type string $tag Input tag name.
399
- * @type string $class Input tag class.
400
- * @type string $div Div wrapper class.
401
- * }
402
- * }
403
- * @type string $redirect_to Optional. URL to redirect to.
404
- * }
405
- * @return string $form The HTML for the form as a string.
406
- */
407
- function login_form( $mixed, $arr = array() ) {
408
-
409
- // Handle legacy use.
410
- if ( is_array( $mixed ) ) {
411
- $page = $mixed['page'];
412
- $arr = $mixed;
413
- } else {
414
- $page = $mixed;
415
- }
416
-
417
-
418
- // Set up redirect_to @todo This could be done in a separate method usable by both login & reg.
419
- if ( isset( $_REQUEST['redirect_to'] ) ) {
420
- $redirect_to = $_REQUEST['redirect_to'];
421
- } else {
422
- if ( isset( $arr['redirect_to'] ) ) {
423
- $redirect_to = $arr['redirect_to'];
424
- } else {
425
- $redirect_to = ( isset( $_SERVER['REQUEST_URI'] ) ) ? $_SERVER['REQUEST_URI'] : get_permalink();
426
- }
427
- }
428
-
429
- global $wpmem;
430
-
431
- // set up default wrappers
432
- $defaults = array(
433
-
434
- // wrappers
435
- 'heading_before' => '<legend>',
436
- 'heading_after' => '</legend>',
437
- 'fieldset_before' => '<fieldset>',
438
- 'fieldset_after' => '</fieldset>',
439
- 'main_div_before' => '<div id="wpmem_login">',
440
- 'main_div_after' => '</div>',
441
- 'txt_before' => '',
442
- 'txt_after' => '',
443
- 'row_before' => '',
444
- 'row_after' => '',
445
- 'buttons_before' => '<div class="button_div">',
446
- 'buttons_after' => '</div>',
447
- 'link_before' => '<div class="link-text">',
448
- 'link_after' => '</div>',
449
- 'link_span_before' => '<span class="link-text-%s">',
450
- 'link_span_after' => '</span>',
451
-
452
- // classes & ids
453
- 'form_id' => 'wpmem_' . $arr['action'] . '_form',
454
- 'form_class' => 'form',
455
- 'button_id' => '',
456
- 'button_class' => 'buttons',
457
-
458
- // other
459
- 'strip_breaks' => true,
460
- 'wrap_inputs' => true,
461
- 'remember_check' => true,
462
- 'n' => "\n",
463
- 't' => "\t",
464
- 'redirect_to' => $redirect_to,
465
- 'login_form_action' => true,
466
-
467
- );
468
-
469
- /**
470
- * Filter the default form arguments.
471
- *
472
- * This filter accepts an array of various elements to replace the form defaults. This
473
- * includes default tags, labels, text, and small items including various booleans.
474
- *
475
- * @since 2.9.0
476
- *
477
- * @param array An array of arguments to merge with defaults. Default null.
478
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
479
- */
480
- $args = apply_filters( 'wpmem_login_form_args', '', $arr['action'] );
481
-
482
- // Merge $args with defaults.
483
- $args = wp_parse_args( $args, $defaults );
484
-
485
- // Build the input rows.
486
- foreach ( $arr['inputs'] as $input ) {
487
- $label = '<label for="' . esc_attr( $input['tag'] ) . '">' . $input['name'] . '</label>';
488
- $field = wpmem_create_formfield( $input['tag'], $input['type'], '', '', $input['class'] );
489
- $field_before = ( $args['wrap_inputs'] ) ? '<div class="' . $this->sanitize_class( $input['div'] ) . '">' : '';
490
- $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
491
- $rows[] = array(
492
- 'row_before' => $args['row_before'],
493
- 'label' => $label,
494
- 'field_before' => $field_before,
495
- 'field' => $field,
496
- 'field_after' => $field_after,
497
- 'row_after' => $args['row_after'],
498
- );
499
- }
500
-
501
- /**
502
- * Filter the array of form rows.
503
- *
504
- * This filter receives an array of the main rows in the form, each array element being
505
- * an array of that particular row's pieces. This allows making changes to individual
506
- * parts of a row without needing to parse through a string of HTML.
507
- *
508
- * @since 2.9.0
509
- *
510
- * @param array $rows An array containing the form rows.
511
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
512
- */
513
- $rows = apply_filters( 'wpmem_login_form_rows', $rows, $arr['action'] );
514
-
515
- // Put the rows from the array into $form.
516
- $form = '';
517
- foreach ( $rows as $row_item ) {
518
- $row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
519
- $row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
520
- $row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
521
- $form.= $row;
522
- }
523
-
524
- // Handle outside elements added to the login form (currently ONLY for login).
525
- if ( 'login' == $arr['action'] && $args['login_form_action'] ) {
526
- ob_start();
527
- /** This action is documented in wp-login.php */
528
- do_action( 'login_form' );
529
- $add_to_form = ob_get_contents();
530
- ob_end_clean();
531
- $form.= $add_to_form;
532
- }
533
-
534
- // Build hidden fields, filter, and add to the form.
535
- $hidden = wpmem_create_formfield( 'redirect_to', 'hidden', esc_url( $args['redirect_to'] ) ) . $args['n'];
536
- $hidden = $hidden . wpmem_create_formfield( 'a', 'hidden', $arr['action'] ) . $args['n'];
537
- $hidden = ( $arr['action'] != 'login' ) ? $hidden . wpmem_create_formfield( 'formsubmit', 'hidden', '1' ) : $hidden;
538
-
539
- /**
540
- * Filter the hidden field HTML.
541
- *
542
- * @since 2.9.0
543
- *
544
- * @param string $hidden The generated HTML of hidden fields.
545
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
546
- */
547
- $form = $form . apply_filters( 'wpmem_login_hidden_fields', $hidden, $arr['action'] );
548
-
549
- // Build the buttons, filter, and add to the form.
550
- if ( $arr['action'] == 'login' ) {
551
- $args['remember_check'] = ( $args['remember_check'] ) ? $args['t'] . wpmem_create_formfield( 'rememberme', 'checkbox', 'forever' ) . '&nbsp;' . '<label for="rememberme">' . $wpmem->get_text( 'remember_me' ) . '</label>&nbsp;&nbsp;' . $args['n'] : '';
552
- $buttons = $args['remember_check'] . $args['t'] . '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
553
- } else {
554
- $buttons = '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
555
- }
556
-
557
- /**
558
- * Filter the HTML for form buttons.
559
- *
560
- * The string includes the buttons, as well as the before/after wrapper elements.
561
- *
562
- * @since 2.9.0
563
- *
564
- * @param string $buttons The generated HTML of the form buttons.
565
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
566
- */
567
- $form = $form . apply_filters( 'wpmem_login_form_buttons', $args['buttons_before'] . $args['n'] . $buttons . $args['buttons_after'] . $args['n'], $arr['action'] );
568
-
569
- $links_array = array(
570
- 'forgot' => array(
571
- 'tag' => 'forgot',
572
- 'link' => add_query_arg( 'a', 'pwdreset', $wpmem->user_pages['profile'] ),
573
- 'page' => 'profile',
574
- 'action' => 'login',
575
- ),
576
- 'register' => array(
577
- 'tag' => 'reg',
578
- 'link' => $wpmem->user_pages['register'],
579
- 'page' => 'register',
580
- 'action' => 'login',
581
- ),
582
- 'username' => array(
583
- 'tag' => 'username',
584
- 'link' => add_query_arg( 'a', 'getusername', $wpmem->user_pages['profile'] ),
585
- 'page' => 'profile',
586
- 'action' => 'pwdreset',
587
- ),
588
- );
589
- foreach ( $links_array as $key => $value ) {
590
- $tag = $value['tag'];
591
- if ( ( $wpmem->user_pages[ $value['page'] ] || 'members' == $page ) && $value['action'] == $arr['action'] ) {
592
- /**
593
- * Filters register, forgot password, and forgot username links.
594
- *
595
- * @since 2.8.0
596
- * @since 3.1.7 Combined all to a single process.
597
- * @since 3.2.5 Added $tag parameter.
598
- *
599
- * @param string The raw link.
600
- * @param string $tag forgot|reg|pwdreset.
601
- */
602
- $link = apply_filters( "wpmem_{$tag}_link", $value['link'], $tag );
603
- $str = $wpmem->get_text( "{$key}_link_before" ) . '<a href="' . esc_url( $link ) . '">' . $wpmem->get_text( "{$key}_link" ) . '</a>';
604
- $link_str = $args['link_before'];
605
- $link_str.= ( '' != $args['link_span_before'] ) ? sprintf( $args['link_span_before'], $key ) : '';
606
- /**
607
- * Filters the register, forgot password, and forgot username links HTML.
608
- *
609
- * @since 2.9.0
610
- * @since 3.0.9 Added $link parameter.
611
- * @since 3.1.7 Combined all to a single process.
612
- * @since 3.2.5 Added $tag parameter.
613
- *
614
- * @param string $str The link HTML.
615
- * @param string $link The link.
616
- * @param string $tag forgot|reg|pwdreset.
617
- */
618
- $link_str.= apply_filters( "wpmem_{$tag}_link_str", $str, $link, $tag );
619
- $link_str.= ( '' != $args['link_span_after'] ) ? $args['link_span_after'] : '';
620
- $link_str.= $args['link_after'] . $args['n'];
621
- /*
622
- * If this is the register link, and the current post type is set to
623
- * display the register form, and the current page is not the login
624
- * page, then do not add the register link, otherwise add the link.
625
- */
626
- if ( 'register' == $key ) {
627
- if ( ! isset( $wpmem->user_pages['register'] ) || '' == $wpmem->user_pages['register'] ) {
628
- $form = $form;
629
- } else {
630
- if ( isset( $wpmem->user_pages['login'] ) && '' != $wpmem->user_pages['login'] ) {
631
- $form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && wpmem_current_url( true, false ) != wpmem_login_url() ) ? $form : $form . $link_str;
632
- } else {
633
- global $post;
634
- if ( has_shortcode( $post->post_content, 'wpmem_profile' ) ) {
635
- $form = $form;
636
- } else {
637
- $form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && ! has_shortcode( $post->post_content, 'wpmem_form' ) ) ? $form : $form . $link_str;
638
- }
639
- }
640
- }
641
- } else {
642
- $form = $form . $link_str;
643
- }
644
- }
645
- }
646
-
647
- // Apply the heading.
648
- $form = $args['heading_before'] . $arr['heading'] . $args['heading_after'] . $args['n'] . $form;
649
-
650
- // Apply fieldset wrapper.
651
- $form = $args['fieldset_before'] . $args['n'] . $form . $args['fieldset_after'] . $args['n'];
652
-
653
- // Apply form wrapper.
654
- $form = '<form action="' . esc_url( get_permalink() ) . '" method="POST" id="' . $this->sanitize_class( $args['form_id'] ) . '" class="' . $this->sanitize_class( $args['form_class'] ) . '">' . $args['n'] . $form . '</form>';
655
-
656
- // Apply anchor.
657
- $form = '<a id="' . esc_attr( $arr['action'] ) . '"></a>' . $args['n'] . $form;
658
-
659
- // Apply main wrapper.
660
- $form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'];
661
-
662
- // Apply wpmem_txt wrapper.
663
- $form = $args['txt_before'] . $form . $args['txt_after'];
664
-
665
- // Remove line breaks.
666
- $form = ( $args['strip_breaks'] ) ? str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
667
-
668
- /**
669
- * Filter the generated HTML of the entire form.
670
- *
671
- * @since 2.7.4
672
- *
673
- * @param string $form The HTML of the final generated form.
674
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
675
- */
676
- $form = apply_filters( 'wpmem_login_form', $form, $arr['action'] );
677
-
678
- /**
679
- * Filter before the form.
680
- *
681
- * This rarely used filter allows you to stick any string onto the front of
682
- * the generated form.
683
- *
684
- * @since 2.7.4
685
- *
686
- * @param string $str The HTML to add before the form. Default null.
687
- * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
688
- */
689
- $form = apply_filters( 'wpmem_login_form_before', '', $arr['action'] ) . $form;
690
-
691
- return $form;
692
- } // End login_form.
693
-
694
- /**
695
- * Registration Form Builder.
696
- *
697
- * Outputs the form for new user registration and existing user edits.
698
- *
699
- * @since 2.5.1
700
- * @since 3.1.7 Moved to forms object class as register_form().
701
- * @since 3.2.5 use_nonce now obsolete (nonce is added automatically).
702
- *
703
- * @global object $wpmem The WP_Members object.
704
- * @global string $wpmem_regchk Used to determine if the form is in an error state.
705
- * @global array $userdata Used to get the user's registration data if they are logged in (user profile edit).
706
- * @param mixed $mixed (optional) String toggles between new registration ('new') and user profile edit ('edit'), or array containing settings arguments.
707
- * @param string $heading (optional) The heading text for the form, null (default) for new registration.
708
- * @return string $form The HTML for the entire form as a string.
709
- */
710
- function register_form( $mixed = 'new', $heading = '', $redirect_to = null ) {
711
-
712
- // Handle legacy use.
713
- if ( is_array( $mixed ) ) {
714
- $id = ( isset( $mixed['id'] ) ) ? $mixed['id'] : '';
715
- $tag = ( isset( $mixed['tag'] ) ) ? $mixed['tag'] : 'new';
716
- $heading = ( isset( $mixed['heading'] ) ) ? $mixed['heading'] : '';
717
- $redirect_to = ( isset( $mixed['redirect_to'] ) ) ? $mixed['redirect_to'] : '';
718
- } else {
719
- $tag = $mixed;
720
- }
721
-
722
- global $wpmem, $wpmem_regchk, $userdata;
723
-
724
- // Set up default wrappers.
725
- $defaults = array(
726
-
727
- // Wrappers.
728
- 'heading_before' => '<legend>',
729
- 'heading_after' => '</legend>',
730
- 'fieldset_before' => '<fieldset>',
731
- 'fieldset_after' => '</fieldset>',
732
- 'main_div_before' => '<div id="wpmem_reg">',
733
- 'main_div_after' => '</div>',
734
- 'txt_before' => '',
735
- 'txt_after' => '',
736
- 'row_before' => '',
737
- 'row_after' => '',
738
- 'buttons_before' => '<div class="button_div">',
739
- 'buttons_after' => '</div>',
740
-
741
- // Classes & ids.
742
- 'form_id' => ( 'new' == $tag ) ? 'wpmem_register_form' : 'wpmem_profile_form',
743
- 'form_class' => 'form',
744
- 'button_id' => '',
745
- 'button_class' => 'buttons',
746
-
747
- // Required field tags and text.
748
- 'req_mark' => $wpmem->get_text( 'register_req_mark' ),
749
- 'req_label' => $wpmem->get_text( 'register_required' ),
750
- 'req_label_before' => '<div class="req-text">',
751
- 'req_label_after' => '</div>',
752
-
753
- // Buttons.
754
- 'show_clear_form' => false,
755
- 'clear_form' => $wpmem->get_text( 'register_clear' ),
756
- 'submit_register' => $wpmem->get_text( 'register_submit' ),
757
- 'submit_update' => $wpmem->get_text( 'profile_submit' ),
758
-
759
- // Other.
760
- 'post_to' => get_permalink(),
761
- 'strip_breaks' => true,
762
- 'wrap_inputs' => true,
763
- 'n' => "\n",
764
- 't' => "\t",
765
-
766
- );
767
-
768
- /**
769
- * Filter the default form arguments.
770
- *
771
- * This filter accepts an array of various elements to replace the form defaults. This
772
- * includes default tags, labels, text, and small items including various booleans.
773
- *
774
- * @since 2.9.0
775
- * @since 3.2.5 Added $id
776
- *
777
- * @param array An array of arguments to merge with defaults. Default null.
778
- * @param string $tag Toggle new registration or profile update. new|edit.
779
- * @param string $id An id for the form (optional).
780
- */
781
- $args = apply_filters( 'wpmem_register_form_args', '', $tag, $id );
782
-
783
- // Merge $args with defaults.
784
- $args = wp_parse_args( $args, $defaults );
785
-
786
- // Get fields.
787
- $wpmem_fields = wpmem_fields( $tag );
788
-
789
- // Fields to skip for user profile update.
790
-
791
- if ( 'edit' == $tag ) {
792
- $pass_arr = array( 'username', 'password', 'confirm_password', 'password_confirm' );
793
- // Skips tos on user edit page, unless they haven't got a value for tos.
794
- if ( isset( $wpmem_fields['tos'] ) && ( $wpmem_fields['tos']['checked_value'] == get_user_meta( $userdata->ID, 'tos', true ) ) ) {
795
- $pass_arr[] = 'tos';
796
- }
797
- foreach ( $pass_arr as $pass ) {
798
- unset( $wpmem_fields[ $pass ] );
799
- }
800
- }
801
-
802
- /**
803
- * Filter the array of form fields.
804
- *
805
- * The form fields are stored in the WP options table as wpmembers_fields. This
806
- * filter can filter that array after the option is retreived before the fields
807
- * are parsed. This allows you to change the fields that may be used in the form
808
- * on the fly.
809
- *
810
- * @since 2.9.0
811
- * @deprecated 3.1.7 Use wpmem_fields instead.
812
- *
813
- * @param array The array of form fields.
814
- * @param string $tag Toggle new registration or profile update. new|edit.
815
- */
816
- $wpmem_fields = apply_filters( 'wpmem_register_fields_arr', $wpmem_fields, $tag );
817
-
818
- $hidden_rows = array();
819
-
820
- // Loop through the remaining fields.
821
- foreach ( $wpmem_fields as $meta_key => $field ) {
822
-
823
- // Start with a clean row.
824
- $val = ''; $label = ''; $input = ''; $field_before = ''; $field_after = '';
825
-
826
- // If the field is set to display and we aren't skipping, construct the row.
827
- if ( $field['register'] ) {
828
-
829
- // Handle hidden fields
830
- if ( 'hidden' == $field['type'] ) {
831
- $do_row = false;
832
- $hidden_rows[ $meta_key ] = wpmem_form_field( array(
833
- 'name' => $meta_key,
834
- 'type' => $field['type'],
835
- 'value' => $field['value'],
836
- 'compare' => $valtochk,
837
- 'required' => $field['required'],
838
- ) );
839
- }
840
-
841
- // Label for all but TOS.
842
- if ( 'tos' != $meta_key ) {
843
-
844
- $class = ( $field['type'] == 'password' || $field['type'] == 'email' || $field['type'] == 'url' ) ? 'text' : $field['type'];
845
-
846
- $label = wpmem_form_label( array(
847
- 'meta_key' => $meta_key, //( 'username' == $meta_key ) ? 'user_login' : $meta_key,
848
- 'label' => __( $field['label'], 'wp-members' ),
849
- 'type' => $field['type'],
850
- 'class' => $class,
851
- 'required' => $field['required'],
852
- 'req_mark' => $args['req_mark']
853
- ) );
854
-
855
- }
856
-
857
- // Gets the field value for edit profile.
858
- if ( ( 'edit' == $tag ) && ( '' == $wpmem->regchk ) ) {
859
- switch ( $meta_key ) {
860
- case( 'description' ):
861
- case( 'textarea' == $field['type'] ):
862
- $val = get_user_meta( $userdata->ID, $meta_key, 'true' ); // esc_textarea() is run when field is created.
863
- break;
864
-
865
- case 'user_email':
866
- case 'confirm_email':
867
- $val = sanitize_email( $userdata->user_email );
868
- break;
869
-
870
- case 'user_url':
871
- $val = $userdata->user_url; // esc_url() is run when the field is created.
872
- break;
873
-
874
- case 'display_name':
875
- $val = sanitize_text_field( $userdata->display_name );
876
- break;
877
-
878
- default:
879
- $val = sanitize_text_field( get_user_meta( $userdata->ID, $meta_key, 'true' ) );
880
- break;
881
- }
882
-
883
- } else {
884
- if ( 'file' == $field['type'] ) {
885
- $val = ( isset( $_FILES[ $meta_key ]['name'] ) ) ? $_FILES[ $meta_key ]['name'] : '' ;
886
- } else {
887
- $val = ( isset( $_POST[ $meta_key ] ) ) ? $_POST[ $meta_key ] : '';
888
- }
889
- }
890
-
891
- // Does the tos field.
892
- if ( 'tos' == $meta_key ) {
893
-
894
- $val = sanitize_text_field( wpmem_get( $meta_key, '' ) );
895
-
896
- // Should be checked by default? and only if form hasn't been submitted.
897
- $val = ( ! $_POST && $field['checked_default'] ) ? $field['checked_value'] : $val;
898
- $input = wpmem_form_field( array(
899
- 'name' => $meta_key,
900
- 'type' => $field['type'],
901
- 'value' => $field['checked_value'],
902
- 'compare' => $val,
903
- 'required' => $field['required'],
904
- ) );
905
- $input = ( $field['required'] ) ? $input . $args['req_mark'] : $input;
906
-
907
- // Determine if TOS is a WP page or not.
908
- $tos_content = stripslashes( get_option( 'wpmembers_tos' ) );
909
- if ( has_shortcode( $tos_content, 'wpmem_tos' ) || has_shortcode( $tos_content, 'wp-members' ) ) {
910
- $link = do_shortcode( $tos_content );
911
- $tos_pop = '<a href="' . esc_url( $link ) . '" target="_blank">';
912
- } else {
913
- $tos_pop = "<a href=\"#\" onClick=\"window.open('" . WPMEM_DIR . "/wp-members-tos.php','mywindow');\">";
914
- }
915
-
916
- /**
917
- * Filter the TOS link text.
918
- *
919
- * @since 2.7.5
920
- *
921
- * @param string The link text.
922
- * @param string $tag Toggle new registration or profile update. new|edit.
923
- */
924
- $tos_link_text = apply_filters( 'wpmem_tos_link_txt', $wpmem->get_text( 'register_tos' ), $tag );
925
-
926
- // If filtered value is not the default label, use that, otherwise use label.
927
- // @note: if default changes, this check must change.
928
- if ( __( 'Please indicate that you agree to the %s Terms of Service %s', 'wp-members' ) == $tos_link_text ) {
929
- if ( __( 'TOS', 'wp-members' ) != $field['label'] && __( 'Terms of Service', 'wp-members' ) != $field['label'] ) {
930
- $tos_link_text = $field['label'];
931
- }
932
- }
933
-
934
- // If tos string does not contain link identifiers (%s), wrap the whole string.
935
- if ( ! strpos( $tos_link_text, '%s' ) ) {
936
- $tos_link_text = '%s' . $tos_link_text . '%s';
937
- }
938
-
939
- $input .= ' ' . sprintf( $tos_link_text, $tos_pop, '</a>' );
940
-
941
- // In previous versions, the div class would end up being the same as the row before.
942
- $field_before = ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '';
943
- $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
944
-
945
- } else {
946
-
947
- // For checkboxes.
948
- if ( 'checkbox' == $field['type'] ) {
949
- $valtochk = $val;
950
- $val = $field['checked_value'];
951
- // if it should it be checked by default (& only if form not submitted), then override above...
952
- if ( $field['checked_default'] && ( ! $_POST && $tag != 'edit' ) ) { $val = $valtochk = $field['checked_value']; }
953
- }
954
-
955
- // For dropdown select.
956
- if ( $field['type'] == 'select' || $field['type'] == 'radio' || $field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' ) {
957
- $valtochk = $val;
958
- $val = $field['values'];
959
- }
960
-
961
- if ( ! isset( $valtochk ) ) { $valtochk = ''; }
962
-
963
- if ( 'edit' == $tag && ( 'file' == $field['type'] || 'image' == $field['type'] ) ) {
964
-
965
- $attachment_url = wp_get_attachment_url( $val );
966
- $empty_file = '<span class="description">' . __( 'None' ) . '</span>';
967
- if ( 'file' == $field['type'] ) {
968
- $input = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '">' . get_the_title( $val ) . '</a>' : $empty_file;
969
- } else {
970
- $input = ( $attachment_url ) ? '<img src="' . esc_url( $attachment_url ) . '">' : $empty_file;
971
- }
972
- $input.= '<br />' . $wpmem->get_text( 'profile_upload' ) . '<br />';
973
- $input.= wpmem_form_field( array(
974
- 'name' => $meta_key,
975
- 'type' => $field['type'],
976
- 'value' => $val,
977
- 'compare' => $valtochk,
978
- ) );
979
-
980
- } else {
981
-
982
- // For all other input types.
983
- $formfield_args = array(
984
- 'name' => $meta_key, // ( 'username' == $meta_key ) ? 'user_login' : $meta_key,
985
- 'type' => $field['type'],
986
- 'value' => $val,
987
- 'compare' => $valtochk,
988
- //'class' => ( $class ) ? $class : 'textbox',
989
- 'required' => $field['required'],
990
- 'placeholder' => ( isset( $field['placeholder'] ) ) ? $field['placeholder'] : '',
991
- 'pattern' => ( isset( $field['pattern'] ) ) ? $field['pattern'] : false,
992
- 'title' => ( isset( $field['title'] ) ) ? $field['title'] : false,
993
- 'min' => ( isset( $field['min'] ) ) ? $field['min'] : false,
994
- 'max' => ( isset( $field['max'] ) ) ? $field['max'] : false,
995
- 'rows' => ( isset( $field['rows'] ) ) ? $field['rows'] : false,
996
- 'cols' => ( isset( $field['cols'] ) ) ? $field['cols'] : false,
997
- );
998
- if ( 'multicheckbox' == $field['type'] || 'multiselect' == $field['type'] ) {
999
- $formfield_args['delimiter'] = $field['delimiter'];
1000
- }
1001
- $input = wpmem_form_field( $formfield_args );
1002
-
1003
- }
1004
-
1005
- // Determine input wrappers.
1006
- $field_before = ( $args['wrap_inputs'] ) ? '<div class="div_' . $class . '">' : '';
1007
- $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
1008
- }
1009
-
1010
- }
1011
-
1012
- // If the row is set to display, add the row to the form array.
1013
- if ( $field['register'] ) {
1014
-
1015
- $values = '';
1016
- if ( 'multicheckbox' == $field['type'] || 'select' == $field['type'] || 'multiselect' == $field['type'] || 'radio' == $field['type'] ) {
1017
- $values = $val;
1018
- $val = $valtochk;
1019
- }
1020
-
1021
- $rows[ $meta_key ] = array(
1022
- 'meta' => $meta_key,
1023
- 'type' => $field['type'],
1024
- 'value' => $val,
1025
- 'values' => $values,
1026
- 'label_text' => __( $field['label'], 'wp-members' ),
1027
- 'row_before' => $args['row_before'],
1028
- 'label' => $label,
1029
- 'field_before' => $field_before,
1030
- 'field' => $input,
1031
- 'field_after' => $field_after,
1032
- 'row_after' => $args['row_after'],
1033
- );
1034
- }
1035
- }
1036
-
1037
- // If captcha is Really Simple CAPTCHA.
1038
- if ( $wpmem->captcha == 2 && $tag != 'edit' ) {
1039
- $row = wpmem_build_rs_captcha();
1040
- $rows['captcha'] = array(
1041
- 'meta' => '',
1042
- 'type' => 'text',
1043
- 'value' => '',
1044
- 'values' => '',
1045
- 'label_text' => $row['label_text'],
1046
- 'row_before' => $args['row_before'],
1047
- 'label' => $row['label'],
1048
- 'field_before' => ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '',
1049
- 'field' => $row['field'],
1050
- 'field_after' => ( $args['wrap_inputs'] ) ? '</div>' : '',
1051
- 'row_after' => $args['row_after'],
1052
- );
1053
- }
1054
-
1055
- /**
1056
- * Filter the array of form rows.
1057
- *
1058
- * This filter receives an array of the main rows in the form, each array element being
1059
- * an array of that particular row's pieces. This allows making changes to individual
1060
- * parts of a row without needing to parse through a string of HTML.
1061
- *
1062
- * @since 2.9.0
1063
- * @since 3.0.9 Added $rows['label_text'].
1064
- * @since 3.1.0 Added $rows['key'].
1065
- * @since 3.1.6 Deprecated $rows['order'].
1066
- *
1067
- * @param array $rows {
1068
- * An array containing the form rows.
1069
- *
1070
- * @type string order Field display order. (deprecated as of 3.1.6)
1071
- * @type string meta Field meta tag (not used for display).
1072
- * @type string type Input field type (not used for display).
1073
- * @type string value Input field value (not used for display).
1074
- * @type string values Possible field values (dropdown, multiple select/check, radio).
1075
- * @type string label_text Raw text for the label (not used for display).
1076
- * @type string row_before Opening wrapper tag around the row.
1077
- * @type string label Label tag.
1078
- * @type string field_before Opening wrapper tag before the input tag.
1079
- * @type string field The field input tag.
1080
- * @type string field_after Closing wrapper tag around the input tag.
1081
- * @type string row_after Closing wrapper tag around the row.
1082
- * }
1083
- * @param string $tag Toggle new registration or profile update. new|edit.
1084
- */
1085
- $rows = apply_filters( 'wpmem_register_form_rows', $rows, $tag );
1086
-
1087
- // Make sure all keys are set just in case someone didn't return a proper array through the filter.
1088
- // @todo Merge this with the next foreach loop so we only have to foreach one time.
1089
- $row_keys = array( 'meta', 'type', 'value', 'values', 'label_text', 'row_before', 'label', 'field_before', 'field', 'field_after', 'row_after' );
1090
- foreach ( $rows as $meta_key => $row ) {
1091
- foreach ( $row_keys as $check_key ) {
1092
- $rows[ $meta_key ][ $check_key ] = ( isset( $rows[ $meta_key ][ $check_key ] ) ) ? $rows[ $meta_key ][ $check_key ] : '';
1093
- }
1094
- }
1095
-
1096
- // Put the rows from the array into $form.
1097
- $form = ''; $enctype = '';
1098
- foreach ( $rows as $row_item ) {
1099
- // Check form to see if we need multipart enctype.
1100
- $enctype = ( $row_item['type'] == 'file' || $row_item['type'] == 'image' ) ? "multipart/form-data" : $enctype;
1101
- // Assemble row pieces.
1102
- $row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
1103
- $row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
1104
- $row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
1105
- $form.= $row;
1106
- }
1107
-
1108
- // Do recaptcha if enabled.
1109
- if ( ( $wpmem->captcha == 1 || $wpmem->captcha == 3 ) && $tag != 'edit' ) { // don't show on edit page!
1110
-
1111
- // Get the captcha options.
1112
- $wpmem_captcha = get_option( 'wpmembers_captcha' );
1113
-
1114
- // Start with a clean row.
1115
- $row = '';
1116
- $row = '<div class="clear"></div>';
1117
- $row.= '<div class="captcha">' . wpmem_inc_recaptcha( $wpmem_captcha['recaptcha'] ) . '</div>';
1118
-
1119
- // Add the captcha row to the form.
1120
- /**
1121
- * Filter the HTML for the CAPTCHA row.
1122
- *
1123
- * @since 2.9.0
1124
- *
1125
- * @param string The HTML for the entire row (includes HTML tags plus reCAPTCHA).
1126
- * @param string $tag Toggle new registration or profile update. new|edit.
1127
- */
1128
- $form.= apply_filters( 'wpmem_register_captcha_row', $args['row_before'] . $row . $args['row_after'], $tag );
1129
- }
1130
-
1131
- // Create hidden fields.
1132
- $var = ( $tag == 'edit' ) ? 'update' : 'register';
1133
- $redirect_to = ( isset( $_REQUEST['redirect_to'] ) ) ? $_REQUEST['redirect_to'] : ( ( $redirect_to ) ? $redirect_to : get_permalink() );
1134
- $hidden_rows['_wpmem_a'] = '<input name="a" type="hidden" value="' . esc_attr( $var ) . '" />';
1135
- $hidden_rows['_wpmem_reg_page'] = '<input name="wpmem_reg_page" type="hidden" value="' . esc_url( get_permalink() ) . '" />';
1136
- if ( $redirect_to != get_permalink() ) {
1137
- $hidden_rows['_wpmem_redirect_to'] = '<input name="redirect_to" type="hidden" value="' . esc_url( $redirect_to ) . '" />';
1138
- }
1139
-
1140
- /**
1141
- * Filter the hidden form rows.
1142
- *
1143
- * @since 3.2.0
1144
- *
1145
- * @param array $hidden_rows
1146
- * @param string $tag
1147
- */
1148
- $hidden_rows = apply_filters( 'wpmem_register_hidden_rows', $hidden_rows, $tag );
1149
-
1150
- // Assemble hidden fields HTML.
1151
- $hidden = '';
1152
- foreach ( $hidden_rows as $hidden_row ) {
1153
- $hidden .= $hidden_row . $args['n'];
1154
- }
1155
-
1156
- /**
1157
- * Filter the hidden field HTML.
1158
- *
1159
- * @since 2.9.0
1160
- *
1161
- * @param string $hidden The generated HTML of hidden fields.
1162
- * @param string $tag Toggle new registration or profile update. new|edit.
1163
- */
1164
- $hidden = apply_filters( 'wpmem_register_hidden_fields', $hidden, $tag );
1165
-
1166
- // Add the hidden fields to the form.
1167
- $form.= $hidden;
1168
-
1169
- // Create buttons and wrapper.
1170
- $button_text = ( $tag == 'edit' ) ? $args['submit_update'] : $args['submit_register'];
1171
- $buttons = ( $args['show_clear_form'] ) ? '<input name="reset" type="reset" value="' . esc_attr( $args['clear_form'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" /> ' . $args['n'] : '';
1172
- $buttons.= '<input name="submit" type="submit" value="' . esc_attr( $button_text ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
1173
-
1174
- /**
1175
- * Filter the HTML for form buttons.
1176
- *
1177
- * The string passed through the filter includes the buttons, as well as the HTML wrapper elements.
1178
- *
1179
- * @since 2.9.0
1180
- *
1181
- * @param string $buttons The generated HTML of the form buttons.
1182
- * @param string $tag Toggle new registration or profile update. new|edit.
1183
- */
1184
- $buttons = apply_filters( 'wpmem_register_form_buttons', $buttons, $tag );
1185
-
1186
- // Add the buttons to the form.
1187
- $form.= $args['buttons_before'] . $args['n'] . $buttons . $args['buttons_after'] . $args['n'];
1188
-
1189
- // Add the required field notation to the bottom of the form.
1190
- $form.= $args['req_label_before'] . $args['req_label'] . $args['req_label_after'];
1191
-
1192
- // Apply the heading.
1193
- /**
1194
- * Filter the registration form heading.
1195
- *
1196
- * @since 2.8.2
1197
- *
1198
- * @param string $str
1199
- * @param string $tag Toggle new registration or profile update. new|edit.
1200
- */
1201
- $heading = ( !$heading ) ? apply_filters( 'wpmem_register_heading', $wpmem->get_text( 'register_heading' ), $tag ) : $heading;
1202
- $form = $args['heading_before'] . $heading . $args['heading_after'] . $args['n'] . $form;
1203
-
1204
- // Apply fieldset wrapper.
1205
- $form = $args['fieldset_before'] . $args['n'] . $form . $args['n'] . $args['fieldset_after'];
1206
-
1207
- // Apply attribution if enabled.
1208
- $form = $form . wpmem_inc_attribution();
1209
-
1210
- // Apply nonce.
1211
- $form = wp_nonce_field( 'wpmem_reg_nonce' ) . $args['n'] . $form;
1212
-
1213
- // Apply form wrapper.
1214
- $enctype = ( $enctype == 'multipart/form-data' ) ? ' enctype="multipart/form-data"' : '';
1215
- $form = '<form name="form" method="post"' . $enctype . ' action="' . esc_attr( $args['post_to'] ) . '" id="' . $this->sanitize_class( $args['form_id'] ) . '" class="' . $this->sanitize_class( $args['form_class'] ) . '">' . $args['n'] . $form . $args['n'] . '</form>';
1216
-
1217
- // Apply anchor.
1218
- $form = '<a id="register"></a>' . $args['n'] . $form;
1219
-
1220
- // Apply main div wrapper.
1221
- $form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'] . $args['n'];
1222
-
1223
- // Apply wpmem_txt wrapper.
1224
- $form = $args['txt_before'] . $form . $args['txt_after'];
1225
-
1226
- // Remove line breaks if enabled for easier filtering later.
1227
- $form = ( $args['strip_breaks'] ) ? $this->strip_breaks( $form, $rows ) : $form; //str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
1228
-
1229
- /**
1230
- * Filter the generated HTML of the entire form.
1231
- *
1232
- * @since 2.7.4
1233
- *
1234
- * @param string $form The HTML of the final generated form.
1235
- * @param string $tag Toggle new registration or profile update. new|edit.
1236
- * @param array $rows {
1237
- * An array containing the form rows.
1238
- *
1239
- * @type string order Field display order.
1240
- * @type string meta Field meta tag (not used for display).
1241
- * @type string type Input field type (not used for display).
1242
- * @type string value Input field value (not used for display).
1243
- * @type string values The possible values for the field (dropdown, multiple select/checkbox, radio group).
1244
- * @type string label_text Raw text for the label (not used for display).
1245
- * @type string row_before Opening wrapper tag around the row.
1246
- * @type string label Label tag.
1247
- * @type string field_before Opening wrapper tag before the input tag.
1248
- * @type string field The field input tag.
1249
- * @type string field_after Closing wrapper tag around the input tag.
1250
- * @type string row_after Closing wrapper tag around the row.
1251
- * }
1252
- * @param string $hidden The HTML string of hidden fields
1253
- */
1254
- $form = apply_filters( 'wpmem_register_form', $form, $tag, $rows, $hidden );
1255
-
1256
- /**
1257
- * Filter before the form.
1258
- *
1259
- * This rarely used filter allows you to stick any string onto the front of
1260
- * the generated form.
1261
- *
1262
- * @since 2.7.4
1263
- *
1264
- * @param string $str The HTML to add before the form. Default null.
1265
- * @param string $tag Toggle new registration or profile update. new|edit.
1266
- */
1267
- $form = apply_filters( 'wpmem_register_form_before', '', $tag ) . $form;
1268
-
1269
- // Return the generated form.
1270
- return $form;
1271
- } // End register_form().
1272
-
1273
- /**
1274
- * Strip line breaks from form.
1275
- *
1276
- * Function removes line breaks and tabs. Checks for textarea fields
1277
- * before stripping line breaks.
1278
- *
1279
- * @since 3.1.8
1280
- *
1281
- * @param string $form
1282
- * @param array $rows
1283
- * @return string $form
1284
- */
1285
- function strip_breaks( $form, $rows ) {
1286
- foreach( $rows as $key => $row ) {
1287
- if ( 'textarea' == $row['type'] ) {
1288
- $textareas[ $key ] = $row['field'];
1289
- }
1290
- }
1291
- $form = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form );
1292
- if ( ! empty ( $textareas ) ) {
1293
- foreach ( $textareas as $textarea ) {
1294
- $stripped = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $textarea );
1295
- $form = str_replace( $stripped, $textarea, $form );
1296
- }
1297
- }
1298
- return $form;
1299
- }
1300
-
1301
- /**
1302
- * Login Dialog.
1303
- *
1304
- * Loads the login form for user login.
1305
- *
1306
- * @since 1.8
1307
- * @since 3.1.4 Global $wpmem_regchk no longer needed.
1308
- * @since 3.2.0 Moved to forms class, renamed do_login_form().
1309
- *
1310
- * @global object $post The WordPress Post object.
1311
- * @global object $wpmem The WP_Members object.
1312
- * @param string $page If the form is being displayed in place of blocked content. Default: page.
1313
- * @param string $redirect_to Redirect URL. Default: null.
1314
- * @param string $show If the form is being displayed in place of blocked content. Default: show.
1315
- * @return string $str The generated html for the login form.
1316
- */
1317
- function do_login_form( $page = "page", $redirect_to = null, $show = 'show' ) {
1318
-
1319
- global $post, $wpmem;
1320
-
1321
- $str = '';
1322
-
1323
- if ( $page == "page" ) {
1324
-
1325
- if ( $wpmem->regchk != "success" ) {
1326
-
1327
- $dialogs = get_option( 'wpmembers_dialogs' );
1328
-
1329
- // This shown above blocked content.
1330
- $msg = $wpmem->get_text( 'restricted_msg' );
1331
- $msg = ( $dialogs['restricted_msg'] == $msg ) ? $msg : __( stripslashes( $dialogs['restricted_msg'] ), 'wp-members' );
1332
- $str = '<div id="wpmem_restricted_msg"><p>' . $msg . '</p></div>';
1333
-
1334
- /**
1335
- * Filter the post restricted message.
1336
- *
1337
- * @since 2.7.3
1338
- * @since 3.2.0 Added raw message string and HTML as separate params.
1339
- *
1340
- * @param string $str The post restricted message with HTML.
1341
- * @param string $msg The raw message string.
1342
- * @param string The 'before' HTML wrapper.
1343
- * @param string The 'after' HTML wrapper.
1344
- */
1345
- $str = apply_filters( 'wpmem_restricted_msg', $str, $msg, '<div id="wpmem_restricted_msg"><p>', '</p></div>' );
1346
-
1347
- }
1348
- }
1349
-
1350
- // Create the default inputs.
1351
- $default_inputs = array(
1352
- array(
1353
- 'name' => $wpmem->get_text( 'login_username' ),
1354
- 'type' => 'text',
1355
- 'tag' => 'log',
1356
- 'class' => 'username',
1357
- 'div' => 'div_text',
1358
- ),
1359
- array(
1360
- 'name' => $wpmem->get_text( 'login_password' ),
1361
- 'type' => 'password',
1362
- 'tag' => 'pwd',
1363
- 'class' => 'password',
1364
- 'div' => 'div_text',
1365
- ),
1366
- );
1367
-
1368
- /**
1369
- * Filter the array of login form fields.
1370
- *
1371
- * @since 2.9.0
1372
- *
1373
- * @param array $default_inputs An array matching the elements used by default.
1374
- */
1375
- $default_inputs = apply_filters( 'wpmem_inc_login_inputs', $default_inputs );
1376
-
1377
- $defaults = array(
1378
- 'heading' => $wpmem->get_text( 'login_heading' ),
1379
- 'action' => 'login',
1380
- 'button_text' => $wpmem->get_text( 'login_button' ),
1381
- 'inputs' => $default_inputs,
1382
- 'redirect_to' => $redirect_to,
1383
- );
1384
-
1385
- /**
1386
- * Filter the arguments to override login form defaults.
1387
- *
1388
- * @since 2.9.0
1389
- *
1390
- * @param array $args An array of arguments to use. Default null.
1391
- */
1392
- $args = apply_filters( 'wpmem_inc_login_args', '' );
1393
-
1394
- $arr = wp_parse_args( $args, $defaults );
1395
-
1396
- $str = ( $show == 'show' ) ? $str . wpmem_login_form( $page, $arr ) : $str;
1397
-
1398
- return $str;
1399
- }
1400
-
1401
- /**
1402
- * Change Password Dialog.
1403
- *
1404
- * Loads the form for changing password.
1405
- *
1406
- * @since 2.0.0
1407
- * @since 3.2.0 Moved to forms class, renamed do_changepassword_form().
1408
- *
1409
- * @global object $wpmem The WP_Members object.
1410
- * @return string $str The generated html for the change password form.
1411
- */
1412
- function do_changepassword_form() {
1413
-
1414
- global $wpmem;
1415
-
1416
- // create the default inputs
1417
- $default_inputs = array(
1418
- array(
1419
- 'name' => $wpmem->get_text( 'pwdchg_password1' ),
1420
- 'type' => 'password',
1421
- 'tag' => 'pass1',
1422
- 'class' => 'password',
1423
- 'div' => 'div_text',
1424
- ),
1425
- array(
1426
- 'name' => $wpmem->get_text( 'pwdchg_password2' ),
1427
- 'type' => 'password',
1428
- 'tag' => 'pass2',
1429
- 'class' => 'password',
1430
- 'div' => 'div_text',
1431
- ),
1432
- );
1433
-
1434
- /**
1435
- * Filter the array of change password form fields.
1436
- *
1437
- * @since 2.9.0
1438
- *
1439
- * @param array $default_inputs An array matching the elements used by default.
1440
- */
1441
- $default_inputs = apply_filters( 'wpmem_inc_changepassword_inputs', $default_inputs );
1442
-
1443
- $defaults = array(
1444
- 'heading' => $wpmem->get_text( 'pwdchg_heading' ),
1445
- 'action' => 'pwdchange',
1446
- 'button_text' => $wpmem->get_text( 'pwdchg_button' ),
1447
- 'inputs' => $default_inputs,
1448
- );
1449
-
1450
- /**
1451
- * Filter the arguments to override change password form defaults.
1452
- *
1453
- * @since 2.9.0
1454
- *
1455
- * @param array $args An array of arguments to use. Default null.
1456
- */
1457
- $args = apply_filters( 'wpmem_inc_changepassword_args', '' );
1458
-
1459
- $arr = wp_parse_args( $args, $defaults );
1460
-
1461
- $str = wpmem_login_form( 'page', $arr );
1462
-
1463
- return $str;
1464
- }
1465
-
1466
- /**
1467
- * Reset Password Dialog.
1468
- *
1469
- * Loads the form for resetting password.
1470
- *
1471
- * @since 2.1.0
1472
- * @since 3.2.0 Moved to forms class, renamed do_resetpassword_form().
1473
- *
1474
- * @global object $wpmem The WP_Members object.
1475
- * @return string $str The generated html fo the reset password form.
1476
- */
1477
- function do_resetpassword_form() {
1478
-
1479
- global $wpmem;
1480
-
1481
- // Create the default inputs.
1482
- $default_inputs = array(
1483
- array(
1484
- 'name' => $wpmem->get_text( 'pwdreset_username' ),
1485
- 'type' => 'text',
1486
- 'tag' => 'user',
1487
- 'class' => 'username',
1488
- 'div' => 'div_text',
1489
- ),
1490
- array(
1491
- 'name' => $wpmem->get_text( 'pwdreset_email' ),
1492
- 'type' => 'text',
1493
- 'tag' => 'email',
1494
- 'class' => 'password',
1495
- 'div' => 'div_text',
1496
- ),
1497
- );
1498
-
1499
- /**
1500
- * Filter the array of reset password form fields.
1501
- *
1502
- * @since 2.9.0
1503
- *
1504
- * @param array $default_inputs An array matching the elements used by default.
1505
- */
1506
- $default_inputs = apply_filters( 'wpmem_inc_resetpassword_inputs', $default_inputs );
1507
-
1508
- $defaults = array(
1509
- 'heading' => $wpmem->get_text( 'pwdreset_heading' ),
1510
- 'action' => 'pwdreset',
1511
- 'button_text' => $wpmem->get_text( 'pwdreset_button' ),
1512
- 'inputs' => $default_inputs,
1513
- );
1514
-
1515
- /**
1516
- * Filter the arguments to override reset password form defaults.
1517
- *
1518
- * @since 2.9.0
1519
- *
1520
- * @param array $args An array of arguments to use. Default null.
1521
- */
1522
- $args = apply_filters( 'wpmem_inc_resetpassword_args', '' );
1523
-
1524
- $arr = wp_parse_args( $args, $defaults );
1525
-
1526
- $str = wpmem_login_form( 'page', $arr );
1527
-
1528
- return $str;
1529
- }
1530
-
1531
- /**
1532
- * Forgot Username Form.
1533
- *
1534
- * Loads the form for retrieving a username.
1535
- *
1536
- * @since 3.0.8
1537
- * @since 3.2.0 Moved to forms class, renamed do_forgotusername_form().
1538
- *
1539
- * @global object $wpmem The WP_Members object class.
1540
- * @return string $str The generated html for the forgot username form.
1541
- */
1542
- function do_forgotusername_form() {
1543
-
1544
- global $wpmem;
1545
-
1546
- // create the default inputs
1547
- $default_inputs = array(
1548
- array(
1549
- 'name' => $wpmem->get_text( 'username_email' ),
1550
- 'type' => 'text',
1551
- 'tag' => 'user_email',
1552
- 'class' => 'username',
1553
- 'div' => 'div_text',
1554
- ),
1555
- );
1556
-
1557
- /**
1558
- * Filter the array of forgot username form fields.
1559
- *
1560
- * @since 2.9.0
1561
- *
1562
- * @param array $default_inputs An array matching the elements used by default.
1563
- */
1564
- $default_inputs = apply_filters( 'wpmem_inc_forgotusername_inputs', $default_inputs );
1565
-
1566
- $defaults = array(
1567
- 'heading' => $wpmem->get_text( 'username_heading' ),
1568
- 'action' => 'getusername',
1569
- 'button_text' => $wpmem->get_text( 'username_button' ),
1570
- 'inputs' => $default_inputs,
1571
- );
1572
-
1573
- /**
1574
- * Filter the arguments to override change password form defaults.
1575
- *
1576
- * @since
1577
- *
1578
- * @param array $args An array of arguments to use. Default null.
1579
- */
1580
- $args = apply_filters( 'wpmem_inc_forgotusername_args', '' );
1581
-
1582
- $arr = wp_parse_args( $args, $defaults );
1583
-
1584
- $str = wpmem_login_form( 'page', $arr );
1585
-
1586
- return $str;
1587
- }
1588
-
1589
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1590
  } // End of WP_Members_Forms class.
1
+ <?php
2
+ /**
3
+ * The WP_Members Forms Class.
4
+ *
5
+ * @package WP-Members
6
+ * @subpackage WP_Members Forms Object Class
7
+ * @since 3.1.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit();
13
+ }
14
+
15
+ class WP_Members_Forms {
16
+
17
+ /**
18
+ * Plugin initialization function.
19
+ *
20
+ * @since 3.1.0
21
+ */
22
+ function __construct() {
23
+
24
+ }
25
+
26
+ /**
27
+ * Creates form fields
28
+ *
29
+ * Creates various form fields and returns them as a string.
30
+ *
31
+ * @since 3.1.0
32
+ * @since 3.1.1 Added $delimiter.
33
+ * @since 3.1.2 Changed $valtochk to $compare.
34
+ * @since 3.1.6 Added $placeholder.
35
+ * @since 3.1.7 Added number type & $min, $max, $title and $pattern attributes.
36
+ * @since 3.2.0 Added $id argument.
37
+ * @since 3.2.4 Added radio group and multiple checkbox individual item labels.
38
+ *
39
+ * @global object $wpmem The WP_Members object class.
40
+ * @param array $args {
41
+ * @type string $id
42
+ * @type string $name
43
+ * @type string $type
44
+ * @type string $value
45
+ * @type string $compare
46
+ * @type string $class
47
+ * @type boolean $required
48
+ * @type string $delimiter
49
+ * @type string $placeholder
50
+ * @type string $pattern
51
+ * @type string $title
52
+ * @type string $min
53
+ * @type string $max
54
+ * @type string $rows Number of rows for a textarea (default:5).
55
+ * @type string $cols Number of columns for a textarea (default:20).
56
+ * }
57
+ * @return string $str The field returned as a string.
58
+ */
59
+ function create_form_field( $args ) {
60
+
61
+ global $wpmem;
62
+
63
+ // Set defaults for most possible $args.
64
+ $id = ( isset( $args['id'] ) ) ? esc_attr( $args['id'] ) : esc_attr( $args['name'] );
65
+ $name = esc_attr( $args['name'] );
66
+ $type = esc_attr( $args['type'] );
67
+ $value = ( isset( $args['value'] ) ) ? maybe_unserialize( $args['value'] ) : '';
68
+ $compare = ( isset( $args['compare'] ) ) ? $args['compare'] : '';
69
+ $class = ( isset( $args['class'] ) ) ? $args['class'] : 'textbox';
70
+ $required = ( isset( $args['required'] ) ) ? $args['required'] : false;
71
+ $delimiter = ( isset( $args['delimiter'] ) ) ? $args['delimiter'] : '|';
72
+ $placeholder = ( isset( $args['placeholder'] ) ) ? $args['placeholder'] : false;
73
+ $pattern = ( isset( $args['pattern'] ) ) ? $args['pattern'] : false;
74
+ $title = ( isset( $args['title'] ) ) ? $args['title'] : false;
75
+
76
+ // Handle field creation by type.
77
+ switch ( $type ) {
78
+
79
+ /*
80
+ * Field types text|url|email|number|date are all handled essentially the
81
+ * same. The primary differences are CSS class (with a default fallback
82
+ * of 'textbox'), how values are escaped, and the application of min|max
83
+ * values for number fields.
84
+ */
85
+ case "text":
86
+ case "url":
87
+ case "email":
88
+ case "number":
89
+ case "date":
90
+ $class = ( 'textbox' == $class ) ? "textbox" : $this->sanitize_class( $class );
91
+ switch ( $type ) {
92
+ case 'url':
93
+ $value = esc_url( $value );
94
+ break;
95
+ case 'email':
96
+ $value = esc_attr( wp_unslash( $value ) );
97
+ break;
98
+ default:
99
+ $value = stripslashes( esc_attr( $value ) ); // @todo Could email and default be combined? Both seem to unslash and esc_attr().
100
+ break;
101
+ }
102
+ $required = ( $required ) ? ' required' : '';
103
+ $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
104
+ $pattern = ( $pattern ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
105
+ $title = ( $title ) ? ' title="' . esc_attr( $title ) . '"' : '';
106
+ $min = ( isset( $args['min'] ) && $args['min'] != '' ) ? ' min="' . esc_attr( $args['min'] ) . '"' : '';
107
+ $max = ( isset( $args['max'] ) && $args['max'] != '' ) ? ' max="' . esc_attr( $args['max'] ). '"' : '';
108
+ $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"$value\" class=\"$class\"$placeholder$title$pattern$min$max" . ( ( $required ) ? " required " : "" ) . " />";
109
+ break;
110
+
111
+ case "password":
112
+ $class = $this->sanitize_class( $class );
113
+ $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
114
+ $pattern = ( $pattern ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
115
+ $title = ( $title ) ? ' title="' . esc_attr( $title ) . '"' : '';
116
+ $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" class=\"$class\"$placeholder$title$pattern" . ( ( $required ) ? " required " : "" ) . " />";
117
+ break;
118
+
119
+ case "image":
120
+ case "file":
121
+ $class = ( 'textbox' == $class ) ? "file" : $this->sanitize_class( $class );
122
+ $str = "<input name=\"$name\" type=\"file\" id=\"$id\" value=\"$value\" class=\"$class\"" . ( ( $required ) ? " required " : "" ) . " />";
123
+ break;
124
+
125
+ case "checkbox":
126
+ $class = ( 'textbox' == $class ) ? "checkbox" : $this->sanitize_class( $class );
127
+ $str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"" . esc_attr( $value ) . "\"" . checked( $value, $compare, false ) . ( ( $required ) ? " required " : "" ) . " />";
128
+ break;
129
+
130
+ case "textarea":
131
+ $value = esc_textarea( stripslashes( $value ) ); // stripslashes( esc_textarea( $value ) );
132
+ $class = ( 'textbox' == $class ) ? "textarea" : $this->sanitize_class( $class );
133
+ $placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '';
134
+ $rows = ( isset( $args['rows'] ) && $args['rows'] ) ? esc_attr( $args['rows'] ) : '5';
135
+ $cols = ( isset( $args['cols'] ) && $args['cols'] ) ? esc_attr( $args['cols'] ) : '20';
136
+ $str = "<textarea cols=\"$cols\" rows=\"$rows\" name=\"$name\" id=\"$id\" class=\"$class\"$placeholder" . ( ( $required ) ? " required " : "" ) . ">$value</textarea>";
137
+ break;
138
+
139
+ case "hidden":
140
+ $str = "<input name=\"$name\" type=\"$type\" value=\"" . esc_attr( $value ) . "\" />";
141
+ break;
142
+
143
+ case "option":
144
+ $str = "<option value=\"" . esc_attr( $value ) . "\" " . selected( $value, $compare, false ) . " >$name</option>";
145
+ break;
146
+
147
+ case "select":
148
+ case "multiselect":
149
+ case "membership":
150
+ $class = ( 'textbox' == $class && 'multiselect' != $type ) ? "dropdown" : $class;
151
+ $class = ( 'textbox' == $class && 'multiselect' == $type ) ? "multiselect" : $class;
152
+ $pname = ( 'multiselect' == $type ) ? $name . "[]" : $name;
153
+ $str = "<select name=\"$pname\" id=\"$id\" class=\"$class\"" . ( ( 'multiselect' == $type ) ? " multiple " : "" ) . ( ( $required ) ? " required " : "" ) . ">\n";
154
+ if ( 'membership' == $type ) {
155
+ $value = array( 'Choose membership|' );
156
+ foreach( $wpmem->membership->products as $membership_key => $membership_value ) {
157
+ $value[] = $membership_value['title'] . '|' . $membership_key;
158
+ }
159
+ }
160
+ foreach ( $value as $option ) {
161
+ $pieces = explode( '|', $option );
162
+ if ( 'multiselect' == $type ) {
163
+ $chk = '';
164
+ $values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
165
+ } else {
166
+ $chk = $compare;
167
+ $values = array();
168
+ }
169
+ if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
170
+ $chk = ( ( isset( $pieces[2] ) && '' == $compare ) || in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk;
171
+ } else {
172
+ $chk = 'not selected';
173
+ }
174
+ $str = $str . "<option value=\"$pieces[1]\"" . selected( $pieces[1], $chk, false ) . ">" . __( $pieces[0], 'wp-members' ) . "</option>\n";
175
+ }
176
+ $str = $str . "</select>";
177
+ break;
178
+
179
+ case "multicheckbox":
180
+ $class = ( 'textbox' == $class ) ? "checkbox" : $class;
181
+ $str = '';
182
+ $num = 1;
183
+ foreach ( $value as $option ) {
184
+ $pieces = explode( '|', $option );
185
+ $values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
186
+ $chk = ( isset( $pieces[2] ) && '' == $compare ) ? $pieces[1] : '';
187
+ if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
188
+ $id_value = esc_attr( $id . '[' . $pieces[1] . ']' );
189
+ $label = wpmem_form_label( array( 'meta_key'=>$id_value, 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'radio', 'id'=>$id_value ) );
190
+ $str = $str . $this->create_form_field( array(
191
+ 'id' => $id_value,
192
+ 'name' => $name . '[]',
193
+ 'type' => 'checkbox',
194
+ 'value' => $pieces[1],
195
+ 'compare' => ( in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk,
196
+ ) ) . "&nbsp;" . $label . "<br />\n";
197
+ } else {
198
+ $str = $str . '<span class="div_multicheckbox_separator">' . esc_html( $pieces[0] ) . "</span><br />\n";
199
+ }
200
+ }
201
+ break;
202
+
203
+ case "radio":
204
+ $class = ( 'textbox' == $class ) ? "radio" : $this->sanitize_class( $class );
205
+ $str = '';
206
+ $num = 1;
207
+ foreach ( $value as $option ) {
208
+ $pieces = explode( '|', $option );
209
+ $id_num = $id . '_' . $num;
210
+ if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
211
+ $label = wpmem_form_label( array( 'meta_key'=>esc_attr( $id_num ), 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'radio', 'id'=>esc_attr( "label_" . $id_num ) ) );
212
+ $str = $str . "<input type=\"radio\" name=\"$name\" id=\"" . esc_attr( $id_num ) . "\" value=\"" . esc_attr( $pieces[1] ) . '"' . checked( $pieces[1], $compare, false ) . ( ( $required ) ? " required " : " " ) . "> $label<br />\n";
213
+ $num++;
214
+ } else {
215
+ $str = $str . '<span class="div_radio_separator">' . esc_html( __( $pieces[0], 'wp-members' ) ) . "</span><br />\n";
216
+ }
217
+ }
218
+ break;
219
+
220
+ }
221
+
222
+ return $str;
223
+ } // End create_form_field()
224
+
225
+ /**
226
+ * Create form label.
227
+ *
228
+ * @since 3.1.7
229
+ * @since 3.2.4 Added $id
230
+ *
231
+ * @param array $args {
232
+ * @type string $meta_key
233
+ * @type string $label
234
+ * @type string $type
235
+ * @type string $id (optional)
236
+ * @type string $class (optional)
237
+ * @type string $required (optional)
238
+ * @type string $req_mark (optional)
239
+ * }
240
+ * @return string $label
241
+ */
242
+ function create_form_label( $args ) {
243
+ global $wpmem;
244
+
245
+ $meta_key = $args['meta_key'];
246
+ $label = $args['label'];
247
+ $type = $args['type'];
248
+ $class = ( isset( $args['class'] ) ) ? $args['class'] : false;
249
+ $id = ( isset( $args['id'] ) ) ? $args['id'] : false;
250
+ $required = ( isset( $args['required'] ) ) ? $args['required'] : false;
251
+ $req_mark = ( isset( $args['req_mark'] ) ) ? $args['req_mark'] : false;
252
+
253
+ //$req_mark = ( ! $req_mark ) ? $wpmem->get_text( 'register_req_mark' ) : '*';
254
+
255
+ if ( ! $class ) {
256
+ $class = ( $type == 'password' || $type == 'email' || $type == 'url' ) ? 'text' : $type;
257
+ }
258
+
259
+ $id = ( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
260
+
261
+ $label = '<label for="' . esc_attr( $meta_key ) . '"' . $id . ' class="' . $this->sanitize_class( $class ) . '">' . __( $label, 'wp-members' );
262
+ $label = ( $required ) ? $label . $req_mark : $label;
263
+ $label = $label . '</label>';
264
+
265
+ return $label;
266
+ }
267
+
268
+ /**
269
+ * Sanitizes classes passed to the WP-Members form building functions.
270
+ *
271
+ * This generally uses just sanitize_html_class() but allows for
272
+ * whitespace so multiple classes can be passed (such as "regular-text code").
273
+ *
274
+ * @since 3.2.0
275
+ *
276
+ * @param string $class
277
+ * @return string sanitized_class
278
+ */
279
+ function sanitize_class( $class ) {
280
+ // If no whitespace, just return WP sanitized class.
281
+ if ( ! strpos( $class, ' ' ) ) {
282
+ return sanitize_html_class( $class );
283
+ } else {
284
+ // Break string by whitespace, sanitize individual class names.
285
+ $class_array = explode( ' ', $class );
286
+ $len = count( $class_array ); $i = 0;
287
+ $sanitized_class = '';
288
+ foreach ( $class_array as $single_class ) {
289
+ $sanitized_class .= sanitize_html_class( $single_class );
290
+ $sanitized_class .= ( $i == $len - 1 ) ? '' : ' ';
291
+ $i++;
292
+ }
293
+ return $sanitized_class;
294
+ }
295
+ }
296
+ /**
297
+ * Uploads file from the user.
298
+ *
299
+ * @since 3.1.0
300
+ *
301
+ * @param array $file
302
+ * @param int $user_id
303
+ * @return int|bool
304
+ */
305
+ function do_file_upload( $file = array(), $user_id = false ) {
306
+
307
+ // Filter the upload directory.
308
+ add_filter( 'upload_dir', array( &$this,'file_upload_dir' ) );
309
+
310
+ // Set up user ID for use in upload process.
311
+ $this->file_user_id = ( $user_id ) ? $user_id : 0;
312
+
313
+ // Get WordPress file upload processing scripts.
314
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
315
+
316
+ $file_return = wp_handle_upload( $file, array( 'test_form' => false ) );
317
+
318
+ if ( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
319
+ return false;
320
+ } else {
321
+
322
+ $attachment = array(
323
+ 'post_mime_type' => $file_return['type'],
324
+ 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_return['file'] ) ),
325
+ 'post_content' => '',
326
+ 'post_status' => 'inherit',
327
+ 'guid' => $file_return['url'],
328
+ 'post_author' => ( $user_id ) ? $user_id : '',
329
+ );
330
+
331
+ $attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
332
+
333
+ require_once( ABSPATH . 'wp-admin/includes/image.php' );
334
+ $attachment_data = wp_generate_attachment_metadata( $attachment_id, $file_return['file'] );
335
+ wp_update_attachment_metadata( $attachment_id, $attachment_data );
336
+
337
+ if ( 0 < intval( $attachment_id ) ) {
338
+ // Returns an array with file information.
339
+ return $attachment_id;
340
+ }
341
+ }
342
+
343
+ return false;
344
+ } // End upload_file()
345
+
346
+ /**
347
+ * Sets the file upload directory.
348
+ *
349
+ * This is a filter function for upload_dir.
350
+ *
351
+ * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/upload_dir
352
+ *
353
+ * @since 3.1.0
354
+ *
355
+ * @param array $param {
356
+ * The directory information for upload.
357
+ *
358
+ * @type string $path
359
+ * @type string $url
360
+ * @type string $subdir
361
+ * @type string $basedir
362
+ * @type string $baseurl
363
+ * @type string $error
364
+ * }
365
+ * @return array $param
366
+ */
367
+ function file_upload_dir( $param ) {
368
+ $user_id = ( isset( $this->file_user_id ) ) ? $this->file_user_id : null;
369
+
370
+ $args = array(
371
+ 'user_id' => $user_id,
372
+ 'wpmem_dir' => 'wpmembers/',
373
+ 'user_dir' => 'user_files/' . $user_id,
374
+ );
375
+ /**
376
+ * Filter the user directory elements.
377
+ *
378
+ * @since 3.1.0
379
+ *
380
+ * @param array $args
381
+ */
382
+ $args = apply_filters( 'wpmem_user_upload_dir', $args );
383
+
384
+ $param['subdir'] = '/' . $args['wpmem_dir'] . $args['user_dir'];
385
+ $param['path'] = $param['basedir'] . '/' . $args['wpmem_dir'] . $args['user_dir'];
386
+ $param['url'] = $param['baseurl'] . '/' . $args['wpmem_dir'] . $args['user_dir'];
387
+
388
+ return $param;
389
+ }
390
+
391
+ /**
392
+ * Login Form Builder.
393
+ *
394
+ * Builds the form used for login, change password, and reset password.
395
+ *
396
+ * @since 2.5.1
397
+ * @since 3.1.7 Moved to forms object class as login_form().
398
+ * @since 3.1.7 Added WP action login_form.
399
+ * @since 3.2.6 Added nonce to the short form.
400
+ *
401
+ * @param string $page
402
+ * @param array $arr {
403
+ * The elements needed to generate the form (login|reset password|forgotten password).
404
+ *
405
+ * @type string $heading Form heading text.
406
+ * @type string $action The form action (login|pwdchange|pwdreset|getusername).
407
+ * @type string $button_text Form submit button text.
408
+ * @type array $inputs {
409
+ * The form input values.
410
+ *
411
+ * @type array {
412
+ *
413
+ * @type string $name The field label.
414
+ * @type string $type Input type.
415
+ * @type string $tag Input tag name.
416
+ * @type string $class Input tag class.
417
+ * @type string $div Div wrapper class.
418
+ * }
419
+ * }
420
+ * @type string $redirect_to Optional. URL to redirect to.
421
+ * }
422
+ * @return string $form The HTML for the form as a string.
423
+ */
424
+ function login_form( $mixed, $arr = array() ) {
425
+
426
+ // Handle legacy use.
427
+ if ( is_array( $mixed ) ) {
428
+ $page = $mixed['page'];
429
+ $arr = $mixed;
430
+ } else {
431
+ $page = $mixed;
432
+ }
433
+
434
+
435
+ // Set up redirect_to @todo This could be done in a separate method usable by both login & reg.
436
+ if ( isset( $_REQUEST['redirect_to'] ) ) {
437
+ $redirect_to = $_REQUEST['redirect_to'];
438
+ } else {
439
+ if ( isset( $arr['redirect_to'] ) ) {
440
+ $redirect_to = $arr['redirect_to'];
441
+ } else {
442
+ $redirect_to = ( isset( $_SERVER['REQUEST_URI'] ) ) ? $_SERVER['REQUEST_URI'] : get_permalink();
443
+ }
444
+ }
445
+
446
+ global $wpmem;
447
+
448
+ // set up default wrappers
449
+ $defaults = array(
450
+
451
+ // wrappers
452
+ 'heading_before' => '<legend>',
453
+ 'heading_after' => '</legend>',
454
+ 'fieldset_before' => '<fieldset>',
455
+ 'fieldset_after' => '</fieldset>',
456
+ 'main_div_before' => '<div id="wpmem_login">',
457
+ 'main_div_after' => '</div>',
458
+ 'txt_before' => '',
459
+ 'txt_after' => '',
460
+ 'row_before' => '',
461
+ 'row_after' => '',
462
+ 'buttons_before' => '<div class="button_div">',
463
+ 'buttons_after' => '</div>',
464
+ 'link_before' => '<div class="link-text">',
465
+ 'link_after' => '</div>',
466
+ 'link_span_before' => '<span class="link-text-%s">',
467
+ 'link_span_after' => '</span>',
468
+
469
+ // classes & ids
470
+ 'form_id' => 'wpmem_' . $arr['action'] . '_form',
471
+ 'form_class' => 'form',
472
+ 'button_id' => '',
473
+ 'button_class' => 'buttons',
474
+
475
+ // other
476
+ 'strip_breaks' => true,
477
+ 'wrap_inputs' => true,
478
+ 'remember_check' => true,
479
+ 'n' => "\n",
480
+ 't' => "\t",
481
+ 'redirect_to' => $redirect_to,
482
+ 'login_form_action' => true,
483
+
484
+ );
485
+
486
+ /**
487
+ * Filter the default form arguments.
488
+ *
489
+ * This filter accepts an array of various elements to replace the form defaults. This
490
+ * includes default tags, labels, text, and small items including various booleans.
491
+ *
492
+ * @since 2.9.0
493
+ *
494
+ * @param array An array of arguments to merge with defaults. Default null.
495
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
496
+ */
497
+ $args = apply_filters( 'wpmem_login_form_args', '', $arr['action'] );
498
+
499
+ // Merge $args with defaults.
500
+ $args = wp_parse_args( $args, $defaults );
501
+
502
+ // Build the input rows.
503
+ foreach ( $arr['inputs'] as $input ) {
504
+ $label = '<label for="' . esc_attr( $input['tag'] ) . '">' . $input['name'] . '</label>';
505
+ $field = wpmem_create_formfield( $input['tag'], $input['type'], '', '', $input['class'] );
506
+ $field_before = ( $args['wrap_inputs'] ) ? '<div class="' . $this->sanitize_class( $input['div'] ) . '">' : '';
507
+ $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
508
+ $rows[] = array(
509
+ 'row_before' => $args['row_before'],
510
+ 'label' => $label,
511
+ 'field_before' => $field_before,
512
+ 'field' => $field,
513
+ 'field_after' => $field_after,
514
+ 'row_after' => $args['row_after'],
515
+ );
516
+ }
517
+
518
+ /**
519
+ * Filter the array of form rows.
520
+ *
521
+ * This filter receives an array of the main rows in the form, each array element being
522
+ * an array of that particular row's pieces. This allows making changes to individual
523
+ * parts of a row without needing to parse through a string of HTML.
524
+ *
525
+ * @since 2.9.0
526
+ * @since 3.2.6 Added $arr parameter so all settings are passed.
527
+ *
528
+ * @param array $rows An array containing the form rows.
529
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
530
+ * @param array $arr An array containing all of the form settings.
531
+ */
532
+ $rows = apply_filters( 'wpmem_login_form_rows', $rows, $arr['action'], $arr );
533
+
534
+ // Put the rows from the array into $form.
535
+ $form = '';
536
+ foreach ( $rows as $row_item ) {
537
+ $row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
538
+ $row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
539
+ $row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
540
+ $form.= $row;
541
+ }
542
+
543
+ // Handle outside elements added to the login form (currently ONLY for login).
544
+ if ( 'login' == $arr['action'] && $args['login_form_action'] ) {
545
+ ob_start();
546
+ /** This action is documented in wp-login.php */
547
+ do_action( 'login_form' );
548
+ $add_to_form = ob_get_contents();
549
+ ob_end_clean();
550
+ $form.= $add_to_form;
551
+ }
552
+
553
+ // Build hidden fields, filter, and add to the form.
554
+ $hidden = wpmem_create_formfield( 'redirect_to', 'hidden', esc_url( $args['redirect_to'] ) ) . $args['n'];
555
+ $hidden = $hidden . wpmem_create_formfield( 'a', 'hidden', $arr['action'] ) . $args['n'];
556
+ $hidden = ( $arr['action'] != 'login' ) ? $hidden . wpmem_create_formfield( 'formsubmit', 'hidden', '1' ) : $hidden;
557
+
558
+ /**
559
+ * Filter the hidden field HTML.
560
+ *
561
+ * @since 2.9.0
562
+ *
563
+ * @param string $hidden The generated HTML of hidden fields.
564
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
565
+ */
566
+ $form = $form . apply_filters( 'wpmem_login_hidden_fields', $hidden, $arr['action'] );
567
+
568
+ // Build the buttons, filter, and add to the form.
569
+ if ( $arr['action'] == 'login' ) {
570
+ $args['remember_check'] = ( $args['remember_check'] ) ? $args['t'] . wpmem_create_formfield( 'rememberme', 'checkbox', 'forever' ) . '&nbsp;' . '<label for="rememberme">' . $wpmem->get_text( 'remember_me' ) . '</label>&nbsp;&nbsp;' . $args['n'] : '';
571
+ $buttons = $args['remember_check'] . $args['t'] . '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
572
+ } else {
573
+ $buttons = '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
574
+ }
575
+
576
+ /**
577
+ * Filter the HTML for form buttons.
578
+ *
579
+ * The string includes the buttons, as well as the before/after wrapper elements.
580
+ *
581
+ * @since 2.9.0
582
+ *
583
+ * @param string $buttons The generated HTML of the form buttons.
584
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
585
+ */
586
+ $form = $form . apply_filters( 'wpmem_login_form_buttons', $args['buttons_before'] . $args['n'] . $buttons . $args['buttons_after'] . $args['n'], $arr['action'] );
587
+
588
+ $links_array = array(
589
+ 'forgot' => array(
590
+ 'tag' => 'forgot',
591
+ 'link' => add_query_arg( 'a', 'pwdreset', $wpmem->user_pages['profile'] ),
592
+ 'page' => 'profile',
593
+ 'action' => 'login',
594
+ ),
595
+ 'register' => array(
596
+ 'tag' => 'reg',
597
+ 'link' => $wpmem->user_pages['register'],
598
+ 'page' => 'register',
599
+ 'action' => 'login',
600
+ ),
601
+ 'username' => array(
602
+ 'tag' => 'username',
603
+ 'link' => add_query_arg( 'a', 'getusername', $wpmem->user_pages['profile'] ),
604
+ 'page' => 'profile',
605
+ 'action' => 'pwdreset',
606
+ ),
607
+ );
608
+ foreach ( $links_array as $key => $value ) {
609
+ $tag = $value['tag'];
610
+ if ( ( $wpmem->user_pages[ $value['page'] ] || 'members' == $page ) && $value['action'] == $arr['action'] ) {
611
+ /**
612
+ * Filters register, forgot password, and forgot username links.
613
+ *
614
+ * @since 2.8.0
615
+ * @since 3.1.7 Combined all to a single process.
616
+ * @since 3.2.5 Added $tag parameter.
617
+ *
618
+ * @param string The raw link.
619
+ * @param string $tag forgot|reg|pwdreset.
620
+ */
621
+ $link = apply_filters( "wpmem_{$tag}_link", $value['link'], $tag );
622
+ $str = $wpmem->get_text( "{$key}_link_before" ) . '<a href="' . esc_url( $link ) . '">' . $wpmem->get_text( "{$key}_link" ) . '</a>';
623
+ $link_str = $args['link_before'];
624
+ $link_str.= ( '' != $args['link_span_before'] ) ? sprintf( $args['link_span_before'], $key ) : '';
625
+ /**
626
+ * Filters the register, forgot password, and forgot username links HTML.
627
+ *
628
+ * @since 2.9.0
629
+ * @since 3.0.9 Added $link parameter.
630
+ * @since 3.1.7 Combined all to a single process.
631
+ * @since 3.2.5 Added $tag parameter.
632
+ *
633
+ * @param string $str The link HTML.
634
+ * @param string $link The link.
635
+ * @param string $tag forgot|reg|pwdreset.
636
+ */
637
+ $link_str.= apply_filters( "wpmem_{$tag}_link_str", $str, $link, $tag );
638
+ $link_str.= ( '' != $args['link_span_after'] ) ? $args['link_span_after'] : '';
639
+ $link_str.= $args['link_after'] . $args['n'];
640
+ /*
641
+ * If this is the register link, and the current post type is set to
642
+ * display the register form, and the current page is not the login
643
+ * page, then do not add the register link, otherwise add the link.
644
+ */
645
+ if ( 'register' == $key ) {
646
+ if ( ! isset( $wpmem->user_pages['register'] ) || '' == $wpmem->user_pages['register'] ) {
647
+ $form = $form;
648
+ } else {
649
+ if ( isset( $wpmem->user_pages['login'] ) && '' != $wpmem->user_pages['login'] ) {
650
+ $form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && wpmem_current_url( true, false ) != wpmem_login_url() ) ? $form : $form . $link_str;
651
+ } else {
652
+ global $post;
653
+ if ( has_shortcode( $post->post_content, 'wpmem_profile' ) ) {
654
+ $form = $form;
655
+ } else {
656
+ $form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && ! has_shortcode( $post->post_content, 'wpmem_form' ) ) ? $form : $form . $link_str;
657
+ }
658
+ }
659
+ }
660
+ } else {
661
+ $form = $form . $link_str;
662
+ }
663
+ }
664
+ }
665
+
666
+ // Apply the heading.
667
+ $form = $args['heading_before'] . $arr['heading'] . $args['heading_after'] . $args['n'] . $form;
668
+
669
+ // Apply fieldset wrapper.
670
+ $form = $args['fieldset_before'] . $args['n'] . $form . $args['fieldset_after'] . $args['n'];
671
+
672
+ // Apply nonce.
673
+ $form = wp_nonce_field( 'wpmem_login_nonce', '_wpnonce', true, false ) . $args['n'] . $form;
674
+
675
+ // Apply form wrapper.
676
+ $form = '<form action="' . esc_url( get_permalink() ) . '" method="POST" id="' . $this->sanitize_class( $args['form_id'] ) . '" class="' . $this->sanitize_class( $args['form_class'] ) . '">' . $args['n'] . $form . '</form>';
677
+
678
+ // Apply anchor.
679
+ $form = '<a id="' . esc_attr( $arr['action'] ) . '"></a>' . $args['n'] . $form;
680
+
681
+ // Apply main wrapper.
682
+ $form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'];
683
+
684
+ // Apply wpmem_txt wrapper.
685
+ $form = $args['txt_before'] . $form . $args['txt_after'];
686
+
687
+ // Remove line breaks.
688
+ $form = ( $args['strip_breaks'] ) ? str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
689
+
690
+ /**
691
+ * Filter the generated HTML of the entire form.
692
+ *
693
+ * @since 2.7.4
694
+ *
695
+ * @param string $form The HTML of the final generated form.
696
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
697
+ */
698
+ $form = apply_filters( 'wpmem_login_form', $form, $arr['action'] );
699
+
700
+ /**
701
+ * Filter before the form.
702
+ *
703
+ * This rarely used filter allows you to stick any string onto the front of
704
+ * the generated form.
705
+ *
706
+ * @since 2.7.4
707
+ *
708
+ * @param string $str The HTML to add before the form. Default null.
709
+ * @param string $arr['action'] The action being performed by the form. login|pwdreset|pwdchange|getusername.
710
+ */
711
+ $form = apply_filters( 'wpmem_login_form_before', '', $arr['action'] ) . $form;
712
+
713
+ return $form;
714
+ } // End login_form.
715
+
716
+ /**
717
+ * Registration Form Builder.
718
+ *
719
+ * Outputs the form for new user registration and existing user edits.
720
+ *
721
+ * @since 2.5.1
722
+ * @since 3.1.7 Moved to forms object class as register_form().
723
+ * @since 3.2.5 use_nonce now obsolete (nonce is added automatically).
724
+ *
725
+ * @global object $wpmem The WP_Members object.
726
+ * @global string $wpmem_regchk Used to determine if the form is in an error state.
727
+ * @global array $userdata Used to get the user's registration data if they are logged in (user profile edit).
728
+ * @param mixed $mixed (optional) String toggles between new registration ('new') and user profile edit ('edit'), or array containing settings arguments.
729
+ * @param string $heading (optional) The heading text for the form, null (default) for new registration.
730
+ * @return string $form The HTML for the entire form as a string.
731
+ */
732
+ function register_form( $mixed = 'new', $heading = '', $redirect_to = null ) {
733
+
734
+ // Handle legacy use.
735
+ if ( is_array( $mixed ) ) {
736
+ $id = ( isset( $mixed['id'] ) ) ? $mixed['id'] : '';
737
+ $tag = ( isset( $mixed['tag'] ) ) ? $mixed['tag'] : 'new';
738
+ $heading = ( isset( $mixed['heading'] ) ) ? $mixed['heading'] : '';
739
+ $redirect_to = ( isset( $mixed['redirect_to'] ) ) ? $mixed['redirect_to'] : '';
740
+ } else {
741
+ $tag = $mixed;
742
+ }
743
+
744
+ global $wpmem, $wpmem_regchk, $userdata;
745
+
746
+ // Set up default wrappers.
747
+ $defaults = array(
748
+
749
+ // Wrappers.
750
+ 'heading_before' => '<legend>',
751
+ 'heading_after' => '</legend>',
752
+ 'fieldset_before' => '<fieldset>',
753
+ 'fieldset_after' => '</fieldset>',
754
+ 'main_div_before' => '<div id="wpmem_reg">',
755
+ 'main_div_after' => '</div>',
756
+ 'txt_before' => '',
757
+ 'txt_after' => '',
758
+ 'row_before' => '',
759
+ 'row_after' => '',
760
+ 'buttons_before' => '<div class="button_div">',
761
+ 'buttons_after' => '</div>',
762
+
763
+ // Classes & ids.
764
+ 'form_id' => ( 'new' == $tag ) ? 'wpmem_register_form' : 'wpmem_profile_form',
765
+ 'form_class' => 'form',
766
+ 'button_id' => '',
767
+ 'button_class' => 'buttons',
768
+
769
+ // Required field tags and text.
770
+ 'req_mark' => $wpmem->get_text( 'register_req_mark' ),
771
+ 'req_label' => $wpmem->get_text( 'register_required' ),
772
+ 'req_label_before' => '<div class="req-text">',
773
+ 'req_label_after' => '</div>',
774
+
775
+ // Buttons.
776
+ 'show_clear_form' => false,
777
+ 'clear_form' => $wpmem->get_text( 'register_clear' ),
778
+ 'submit_register' => $wpmem->get_text( 'register_submit' ),
779
+ 'submit_update' => $wpmem->get_text( 'profile_submit' ),
780
+
781
+ // Other.
782
+ 'post_to' => get_permalink(),
783
+ 'strip_breaks' => true,
784
+ 'wrap_inputs' => true,
785
+ 'n' => "\n",
786
+ 't' => "\t",
787
+
788
+ );
789
+
790
+ /**
791
+ * Filter the default form arguments.
792
+ *
793
+ * This filter accepts an array of various elements to replace the form defaults. This
794
+ * includes default tags, labels, text, and small items including various booleans.
795
+ *
796
+ * @since 2.9.0
797
+ * @since 3.2.5 Added $id
798
+ *
799
+ * @param array An array of arguments to merge with defaults. Default null.
800
+ * @param string $tag Toggle new registration or profile update. new|edit.
801
+ * @param string $id An id for the form (optional).
802
+ */
803
+ $args = apply_filters( 'wpmem_register_form_args', '', $tag, $id );
804
+
805
+ // Merge $args with defaults.
806
+ $args = wp_parse_args( $args, $defaults );
807
+
808
+ // Get fields.
809
+ $wpmem_fields = wpmem_fields( $tag );
810
+
811
+ // Fields to skip for user profile update.
812
+
813
+ if ( 'edit' == $tag ) {
814
+ $pass_arr = array( 'username', 'password', 'confirm_password', 'password_confirm' );
815
+ // Skips tos on user edit page, unless they haven't got a value for tos.
816
+ if ( isset( $wpmem_fields['tos'] ) && ( $wpmem_fields['tos']['checked_value'] == get_user_meta( $userdata->ID, 'tos', true ) ) ) {
817
+ $pass_arr[] = 'tos';
818
+ }
819
+ foreach ( $pass_arr as $pass ) {
820
+ unset( $wpmem_fields[ $pass ] );
821
+ }
822
+ }
823
+
824
+ /**
825
+ * Filter the array of form fields.
826
+ *
827
+ * The form fields are stored in the WP options table as wpmembers_fields. This
828
+ * filter can filter that array after the option is retreived before the fields
829
+ * are parsed. This allows you to change the fields that may be used in the form
830
+ * on the fly.
831
+ *
832
+ * @since 2.9.0
833
+ * @deprecated 3.1.7 Use wpmem_fields instead.
834
+ *
835
+ * @param array The array of form fields.
836
+ * @param string $tag Toggle new registration or profile update. new|edit.
837
+ */
838
+ $wpmem_fields = apply_filters( 'wpmem_register_fields_arr', $wpmem_fields, $tag );
839
+
840
+ $hidden_rows = array();
841
+
842
+ // Loop through the remaining fields.
843
+ foreach ( $wpmem_fields as $meta_key => $field ) {
844
+
845
+ // Start with a clean row.
846
+ $val = ''; $label = ''; $input = ''; $field_before = ''; $field_after = '';
847
+
848
+ // If the field is set to display and we aren't skipping, construct the row.
849
+ if ( $field['register'] ) {
850
+
851
+ // Handle hidden fields
852
+ if ( 'hidden' == $field['type'] ) {
853
+ $do_row = false;
854
+ $hidden_rows[ $meta_key ] = wpmem_form_field( array(
855
+ 'name' => $meta_key,
856
+ 'type' => $field['type'],
857
+ 'value' => $field['value'],
858
+ 'compare' => $valtochk,
859
+ 'required' => $field['required'],
860
+ ) );
861
+ }
862
+
863
+ // Label for all but TOS and hidden fields.
864
+ if ( 'tos' != $meta_key && 'hidden' != $field['type'] ) {
865
+
866
+ $class = ( $field['type'] == 'password' || $field['type'] == 'email' || $field['type'] == 'url' ) ? 'text' : $field['type'];
867
+
868
+ $label = wpmem_form_label( array(
869
+ 'meta_key' => $meta_key, //( 'username' == $meta_key ) ? 'user_login' : $meta_key,
870
+ 'label' => __( $field['label'], 'wp-members' ),
871
+ 'type' => $field['type'],
872
+ 'class' => $class,
873
+ 'required' => $field['required'],
874
+ 'req_mark' => $args['req_mark']
875
+ ) );
876
+
877
+ }
878
+
879
+ // Gets the field value for edit profile.
880
+ if ( ( 'edit' == $tag ) && ( '' == $wpmem->regchk ) ) {
881
+ switch ( $meta_key ) {
882
+ case( 'description' ):
883
+ case( 'textarea' == $field['type'] ):
884
+ $val = get_user_meta( $userdata->ID, $meta_key, 'true' ); // esc_textarea() is run when field is created.
885
+ break;
886
+
887
+ case 'user_email':
888
+ case 'confirm_email':
889
+ $val = sanitize_email( $userdata->user_email );
890
+ break;
891
+
892
+ case 'user_url':
893
+ $val = $userdata->user_url; // esc_url() is run when the field is created.
894
+ break;
895
+
896
+ case 'display_name':
897
+ $val = sanitize_text_field( $userdata->display_name );
898
+ break;
899
+
900
+ default:
901
+ $val = sanitize_text_field( get_user_meta( $userdata->ID, $meta_key, 'true' ) );
902
+ break;
903
+ }
904
+
905
+ } else {
906
+ if ( 'file' == $field['type'] ) {
907
+ $val = ( isset( $_FILES[ $meta_key ]['name'] ) ) ? $_FILES[ $meta_key ]['name'] : '' ;
908
+ } else {
909
+ $val = ( isset( $_POST[ $meta_key ] ) ) ? $_POST[ $meta_key ] : '';
910
+ }
911
+ }
912
+
913
+ // Does the tos field.
914
+ if ( 'tos' == $meta_key ) {
915
+
916
+ $val = sanitize_text_field( wpmem_get( $meta_key, '' ) );
917
+
918
+ // Should be checked by default? and only if form hasn't been submitted.
919
+ $val = ( ! $_POST && $field['checked_default'] ) ? $field['checked_value'] : $val;
920
+ $input = wpmem_form_field( array(
921
+ 'name' => $meta_key,
922
+ 'type' => $field['type'],
923
+ 'value' => $field['checked_value'],
924
+ 'compare' => $val,
925
+ 'required' => $field['required'],
926
+ ) );
927
+ $input = ( $field['required'] ) ? $input . $args['req_mark'] : $input;
928
+
929
+ // Determine if TOS is a WP page or not.
930
+ $tos_content = stripslashes( get_option( 'wpmembers_tos' ) );
931
+ if ( has_shortcode( $tos_content, 'wpmem_tos' ) || has_shortcode( $tos_content, 'wp-members' ) ) {
932
+ $tos_link_url = do_shortcode( $tos_content );
933
+ $tos_link_tag = '<a href="' . esc_url( $tos_link_url ) . '" target="_blank">';
934
+ } else {
935
+ $tos_link_url = WPMEM_DIR . "/wp-members-tos.php";
936
+ $tos_link_tag = "<a href=\"#\" onClick=\"window.open('" . $tos_link_url . "','mywindow');\">";
937
+ }
938
+
939
+ /**
940
+ * Filter the TOS link.
941
+ *
942
+ * @since 3.2.6
943
+ *
944
+ * @param string $tos_link_tag
945
+ * @param string $tos_link_url
946
+ */
947
+ $tos_link_tag = apply_filters( 'wpmem_tos_link_tag', $tos_link_tag, $tos_link_url );
948
+
949
+ /**
950
+ * Filter the TOS link text.
951
+ *
952
+ * @since 2.7.5
953
+ *
954
+ * @param string The link text.
955
+ * @param string $tag Toggle new registration or profile update. new|edit.
956
+ */
957
+ $tos_link_text = apply_filters( 'wpmem_tos_link_txt', $wpmem->get_text( 'register_tos' ), $tag );
958
+
959
+ // If filtered value is not the default label, use that, otherwise use label.
960
+ // @note: if default changes, this check must change.
961
+ if ( __( 'Please indicate that you agree to the %s Terms of Service %s', 'wp-members' ) == $tos_link_text ) {
962
+ if ( __( 'TOS', 'wp-members' ) != $field['label'] && __( 'Terms of Service', 'wp-members' ) != $field['label'] ) {
963
+ $tos_link_text = $field['label'];
964
+ }
965
+ }
966
+
967
+ // If tos string does not contain link identifiers (%s), wrap the whole string.
968
+ if ( ! strpos( $tos_link_text, '%s' ) ) {
969
+ $tos_link_text = '%s' . $tos_link_text . '%s';
970
+ }
971
+
972
+ $input .= ' ' . sprintf( $tos_link_text, $tos_link_tag, '</a>' );
973
+
974
+ // In previous versions, the div class would end up being the same as the row before.
975
+ $field_before = ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '';
976
+ $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
977
+
978
+ } elseif ( 'hidden' != $field['type'] ) {
979
+
980
+ // For checkboxes.
981
+ if ( 'checkbox' == $field['type'] ) {
982
+ $valtochk = $val;
983
+ $val = $field['checked_value'];
984
+ // if it should it be checked by default (& only if form not submitted), then override above...
985
+ if ( $field['checked_default'] && ( ! $_POST && $tag != 'edit' ) ) { $val = $valtochk = $field['checked_value']; }
986
+ }
987
+
988
+ // For dropdown select.
989
+ if ( $field['type'] == 'select' || $field['type'] == 'radio' || $field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' ) {
990
+ $valtochk = $val;
991
+ $val = $field['values'];
992
+ }
993
+
994
+ if ( ! isset( $valtochk ) ) { $valtochk = ''; }
995
+
996
+ if ( 'edit' == $tag && ( 'file' == $field['type'] || 'image' == $field['type'] ) ) {
997
+
998
+ $attachment_url = wp_get_attachment_url( $val );
999
+ $empty_file = '<span class="description">' . __( 'None' ) . '</span>';
1000
+ if ( 'file' == $field['type'] ) {
1001
+ $input = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '">' . get_the_title( $val ) . '</a>' : $empty_file;
1002
+ } else {
1003
+ $input = ( $attachment_url ) ? '<img src="' . esc_url( $attachment_url ) . '">' : $empty_file;
1004
+ }
1005
+ $input.= '<br />' . $wpmem->get_text( 'profile_upload' ) . '<br />';
1006
+ $input.= wpmem_form_field( array(
1007
+ 'name' => $meta_key,
1008
+ 'type' => $field['type'],
1009
+ 'value' => $val,
1010
+ 'compare' => $valtochk,
1011
+ ) );
1012
+
1013
+ } else {
1014
+
1015
+ // For all other input types.
1016
+ $formfield_args = array(
1017
+ 'name' => $meta_key, // ( 'username' == $meta_key ) ? 'user_login' : $meta_key,
1018
+ 'type' => $field['type'],
1019
+ 'value' => $val,
1020
+ 'compare' => $valtochk,
1021
+ //'class' => ( $class ) ? $class : 'textbox',
1022
+ 'required' => $field['required'],
1023
+ 'placeholder' => ( isset( $field['placeholder'] ) ) ? $field['placeholder'] : '',
1024
+ 'pattern' => ( isset( $field['pattern'] ) ) ? $field['pattern'] : false,
1025
+ 'title' => ( isset( $field['title'] ) ) ? $field['title'] : false,
1026
+ 'min' => ( isset( $field['min'] ) ) ? $field['min'] : false,
1027
+ 'max' => ( isset( $field['max'] ) ) ? $field['max'] : false,
1028
+ 'rows' => ( isset( $field['rows'] ) ) ? $field['rows'] : false,
1029
+ 'cols' => ( isset( $field['cols'] ) ) ? $field['cols'] : false,
1030
+ );
1031
+ if ( 'multicheckbox' == $field['type'] || 'multiselect' == $field['type'] ) {
1032
+ $formfield_args['delimiter'] = $field['delimiter'];
1033
+ }
1034
+ $input = wpmem_form_field( $formfield_args );
1035
+
1036
+ }
1037
+
1038
+ // Determine input wrappers.
1039
+ $field_before = ( $args['wrap_inputs'] ) ? '<div class="div_' . $class . '">' : '';
1040
+ $field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
1041
+ }
1042
+
1043
+ }
1044
+
1045
+ // If the row is set to display, add the row to the form array.
1046
+ if ( $field['register'] && 'hidden' != $field['type'] ) {
1047
+
1048
+ $values = '';
1049
+ if ( 'multicheckbox' == $field['type'] || 'select' == $field['type'] || 'multiselect' == $field['type'] || 'radio' == $field['type'] ) {
1050
+ $values = $val;
1051
+ $val = $valtochk;
1052
+ }
1053
+
1054
+ $rows[ $meta_key ] = array(
1055
+ 'meta' => $meta_key,
1056
+ 'type' => $field['type'],
1057
+ 'value' => $val,
1058
+ 'values' => $values,
1059
+ 'label_text' => __( $field['label'], 'wp-members' ),
1060
+ 'row_before' => $args['row_before'],
1061
+ 'label' => $label,
1062
+ 'field_before' => $field_before,
1063
+ 'field' => $input,
1064
+ 'field_after' => $field_after,
1065
+ 'row_after' => $args['row_after'],
1066
+ );
1067
+ }
1068
+ }
1069
+
1070
+ // If captcha is Really Simple CAPTCHA.
1071
+ if ( $wpmem->captcha == 2 && $tag != 'edit' ) {
1072
+ $row = wpmem_build_rs_captcha();
1073
+ $rows['captcha'] = array(
1074
+ 'meta' => '',
1075
+ 'type' => 'text',
1076
+ 'value' => '',
1077
+ 'values' => '',
1078
+ 'label_text' => $row['label_text'],
1079
+ 'row_before' => $args['row_before'],
1080
+ 'label' => $row['label'],
1081
+ 'field_before' => ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '',
1082
+ 'field' => $row['field'],
1083
+ 'field_after' => ( $args['wrap_inputs'] ) ? '</div>' : '',
1084
+ 'row_after' => $args['row_after'],
1085
+ );
1086
+ }
1087
+
1088
+ /**
1089
+ * Filter the array of form rows.
1090
+ *
1091
+ * This filter receives an array of the main rows in the form, each array element being
1092
+ * an array of that particular row's pieces. This allows making changes to individual
1093
+ * parts of a row without needing to parse through a string of HTML.
1094
+ *
1095
+ * @since 2.9.0
1096
+ * @since 3.0.9 Added $rows['label_text'].
1097
+ * @since 3.1.0 Added $rows['key'].
1098
+ * @since 3.1.6 Deprecated $rows['order'].
1099
+ *
1100
+ * @param array $rows {
1101
+ * An array containing the form rows.
1102
+ *
1103
+ * @type string order Field display order. (deprecated as of 3.1.6)
1104
+ * @type string meta Field meta tag (not used for display).
1105
+ * @type string type Input field type (not used for display).
1106
+ * @type string value Input field value (not used for display).
1107
+ * @type string values Possible field values (dropdown, multiple select/check, radio).
1108
+ * @type string label_text Raw text for the label (not used for display).
1109
+ * @type string row_before Opening wrapper tag around the row.
1110
+ * @type string label Label tag.
1111
+ * @type string field_before Opening wrapper tag before the input tag.
1112
+ * @type string field The field input tag.
1113
+ * @type string field_after Closing wrapper tag around the input tag.
1114
+ * @type string row_after Closing wrapper tag around the row.
1115
+ * }
1116
+ * @param string $tag Toggle new registration or profile update. new|edit.
1117
+ */
1118
+ $rows = apply_filters( 'wpmem_register_form_rows', $rows, $tag );
1119
+
1120
+ // Make sure all keys are set just in case someone didn't return a proper array through the filter.
1121
+ // @todo Merge this with the next foreach loop so we only have to foreach one time.
1122
+ $row_keys = array( 'meta', 'type', 'value', 'values', 'label_text', 'row_before', 'label', 'field_before', 'field', 'field_after', 'row_after' );
1123
+ foreach ( $rows as $meta_key => $row ) {
1124
+ foreach ( $row_keys as $check_key ) {
1125
+ $rows[ $meta_key ][ $check_key ] = ( isset( $rows[ $meta_key ][ $check_key ] ) ) ? $rows[ $meta_key ][ $check_key ] : '';
1126
+ }
1127
+ }
1128
+
1129
+ // Put the rows from the array into $form.
1130
+ $form = ''; $enctype = '';
1131
+ foreach ( $rows as $row_item ) {
1132
+ // Check form to see if we need multipart enctype.
1133
+ $enctype = ( $row_item['type'] == 'file' || $row_item['type'] == 'image' ) ? "multipart/form-data" : $enctype;
1134
+ // Assemble row pieces.
1135
+ $row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
1136
+ $row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
1137
+ $row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
1138
+ $form.= $row;
1139
+ }
1140
+
1141
+ // Do recaptcha if enabled.
1142
+ if ( ( $wpmem->captcha == 1 || $wpmem->captcha == 3 ) && $tag != 'edit' ) { // don't show on edit page!
1143
+
1144
+ // Get the captcha options.
1145
+ $wpmem_captcha = get_option( 'wpmembers_captcha' );
1146
+
1147
+ // Start with a clean row.
1148
+ $row = '';
1149
+ $row = '<div class="clear"></div>';
1150
+ $row.= '<div class="captcha">' . wpmem_inc_recaptcha( $wpmem_captcha['recaptcha'] ) . '</div>';
1151
+
1152
+ // Add the captcha row to the form.
1153
+ /**
1154
+ * Filter the HTML for the CAPTCHA row.
1155
+ *
1156
+ * @since 2.9.0
1157
+ *
1158
+ * @param string The HTML for the entire row (includes HTML tags plus reCAPTCHA).
1159
+ * @param string $tag Toggle new registration or profile update. new|edit.
1160
+ */
1161
+ $form.= apply_filters( 'wpmem_register_captcha_row', $args['row_before'] . $row . $args['row_after'], $tag );
1162
+ }
1163
+
1164
+ // Create hidden fields.
1165
+ $var = ( $tag == 'edit' ) ? 'update' : 'register';
1166
+ $redirect_to = ( isset( $_REQUEST['redirect_to'] ) ) ? $_REQUEST['redirect_to'] : ( ( $redirect_to ) ? $redirect_to : get_permalink() );
1167
+ $hidden_rows['_wpmem_a'] = '<input name="a" type="hidden" value="' . esc_attr( $var ) . '" />';
1168
+ $hidden_rows['_wpmem_reg_page'] = '<input name="wpmem_reg_page" type="hidden" value="' . esc_url( get_permalink() ) . '" />';
1169
+ if ( $redirect_to != get_permalink() ) {
1170
+ $hidden_rows['_wpmem_redirect_to'] = '<input name="redirect_to" type="hidden" value="' . esc_url( $redirect_to ) . '" />';
1171
+ }
1172
+
1173
+ /**
1174
+ * Filter the hidden form rows.
1175
+ *
1176
+ * @since 3.2.0
1177
+ *
1178
+ * @param array $hidden_rows
1179
+ * @param string $tag
1180
+ */
1181
+ $hidden_rows = apply_filters( 'wpmem_register_hidden_rows', $hidden_rows, $tag );
1182
+
1183
+ // Assemble hidden fields HTML.
1184
+ $hidden = '';
1185
+ foreach ( $hidden_rows as $hidden_row ) {
1186
+ $hidden .= $hidden_row . $args['n'];
1187
+ }
1188
+
1189
+ /**
1190
+ * Filter the hidden field HTML.
1191
+ *
1192
+ * @since 2.9.0
1193
+ *
1194
+ * @param string $hidden The generated HTML of hidden fields.
1195
+ * @param string $tag Toggle new registration or profile update. new|edit.
1196
+ */
1197
+ $hidden = apply_filters( 'wpmem_register_hidden_fields', $hidden, $tag );
1198
+
1199
+ // Add the hidden fields to the form.
1200
+ $form.= $hidden;
1201
+
1202
+ // Create buttons and wrapper.
1203
+ $button_text = ( $tag == 'edit' ) ? $args['submit_update'] : $args['submit_register'];
1204
+ $button_html = array(
1205
+ 'reset' => ( $args['show_clear_form'] ) ? '<input name="reset" type="reset" value="' . esc_attr( $args['clear_form'] ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" /> ' : '',
1206
+ 'submit' => '<input name="submit" type="submit" value="' . esc_attr( $button_text ) . '" class="' . $this->sanitize_class( $args['button_class'] ) . '" />',
1207
+ );
1208
+ $buttons = $button_html['reset'] . $args['n'] . $button_html['submit'] . $args['n'];
1209
+
1210
+ /**
1211
+ * Filter the HTML for form buttons.
1212
+ *
1213
+ * The string passed through the filter includes the buttons, as well as the HTML wrapper elements.
1214
+ *
1215
+ * @since 2.9.0
1216
+ * @since 3.2.6 Added $button_html parameter
1217
+ *
1218
+ * @param string $buttons The generated HTML of the form buttons.
1219
+ * @param string $tag Toggle new registration or profile update. new|edit.
1220
+ * @param array $button_html The individual button html.
1221
+ */
1222
+ $buttons = apply_filters( 'wpmem_register_form_buttons', $buttons, $tag, $button_html );
1223
+
1224
+ // Add the buttons to the form.
1225
+ $form.= $args['buttons_before'] . $args['n'] . $buttons . $args['buttons_after'] . $args['n'];
1226
+
1227
+ // Add the required field notation to the bottom of the form.
1228
+ $form.= $args['req_label_before'] . $args['req_label'] . $args['req_label_after'];
1229
+
1230
+ // Apply the heading.
1231
+ /**
1232
+ * Filter the registration form heading.
1233
+ *
1234
+ * @since 2.8.2
1235
+ *
1236
+ * @param string $str
1237
+ * @param string $tag Toggle new registration or profile update. new|edit.
1238
+ */
1239
+ $heading = ( !$heading ) ? apply_filters( 'wpmem_register_heading', $wpmem->get_text( 'register_heading' ), $tag ) : $heading;
1240
+ $form = $args['heading_before'] . $heading . $args['heading_after'] . $args['n'] . $form;
1241
+
1242
+ // Apply fieldset wrapper.
1243
+ $form = $args['fieldset_before'] . $args['n'] . $form . $args['n'] . $args['fieldset_after'];
1244
+
1245
+ // Apply attribution if enabled.
1246
+ $form = $form . wpmem_inc_attribution();
1247
+
1248
+ // Apply nonce.
1249
+ $form = wp_nonce_field( 'wpmem_reg_nonce', '_wpnonce', true, false ) . $args['n'] . $form;
1250
+
1251
+ // Apply form wrapper.
1252
+ $enctype = ( $enctype == 'multipart/form-data' ) ? ' enctype="multipart/form-data"' : '';
1253
+ $form = '<form name="form" method="post"' . $enctype . ' action="' . esc_attr( $args['post_to'] ) . '" id="' . $this->sanitize_class( $args['form_id'] ) . '" class="' . $this->sanitize_class( $args['form_class'] ) . '">' . $args['n'] . $form . $args['n'] . '</form>';
1254
+
1255
+ // Apply anchor.
1256
+ $form = '<a id="register"></a>' . $args['n'] . $form;
1257
+
1258
+ // Apply main div wrapper.
1259
+ $form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'] . $args['n'];
1260
+
1261
+ // Apply wpmem_txt wrapper.
1262
+ $form = $args['txt_before'] . $form . $args['txt_after'];
1263
+
1264
+ // Remove line breaks if enabled for easier filtering later.
1265
+ $form = ( $args['strip_breaks'] ) ? $this->strip_breaks( $form, $rows ) : $form; //str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
1266
+
1267
+ /**
1268
+ * Filter the generated HTML of the entire form.
1269
+ *
1270
+ * @since 2.7.4
1271
+ *
1272
+ * @param string $form The HTML of the final generated form.
1273
+ * @param string $tag Toggle new registration or profile update. new|edit.
1274
+ * @param array $rows {
1275
+ * An array containing the form rows.
1276
+ *
1277
+ * @type string order Field display order.
1278
+ * @type string meta Field meta tag (not used for display).
1279
+ * @type string type Input field type (not used for display).
1280
+ * @type string value Input field value (not used for display).
1281
+ * @type string values The possible values for the field (dropdown, multiple select/checkbox, radio group).
1282
+ * @type string label_text Raw text for the label (not used for display).
1283
+ * @type string row_before Opening wrapper tag around the row.
1284
+ * @type string label Label tag.
1285
+ * @type string field_before Opening wrapper tag before the input tag.
1286
+ * @type string field The field input tag.
1287
+ * @type string field_after Closing wrapper tag around the input tag.
1288
+ * @type string row_after Closing wrapper tag around the row.
1289
+ * }
1290
+ * @param string $hidden The HTML string of hidden fields
1291
+ */
1292
+ $form = apply_filters( 'wpmem_register_form', $form, $tag, $rows, $hidden );
1293
+
1294
+ /**
1295
+ * Filter before the form.
1296
+ *
1297
+ * This rarely used filter allows you to stick any string onto the front of
1298
+ * the generated form.
1299
+ *
1300
+ * @since 2.7.4
1301
+ *
1302
+ * @param string $str The HTML to add before the form. Default null.
1303
+ * @param string $tag Toggle new registration or profile update. new|edit.
1304
+ */
1305
+ $form = apply_filters( 'wpmem_register_form_before', '', $tag ) . $form;
1306
+
1307
+ // Return the generated form.
1308
+ return $form;
1309
+ } // End register_form().
1310
+
1311
+ /**
1312
+ * Strip line breaks from form.
1313
+ *
1314
+ * Function removes line breaks and tabs. Checks for textarea fields
1315
+ * before stripping line breaks.
1316
+ *
1317
+ * @since 3.1.8
1318
+ *
1319
+ * @param string $form
1320
+ * @param array $rows
1321
+ * @return string $form
1322
+ */
1323
+ function strip_breaks( $form, $rows ) {
1324
+ foreach( $rows as $key => $row ) {
1325
+ if ( 'textarea' == $row['type'] ) {
1326
+ $textareas[ $key ] = $row['field'];
1327
+ }
1328
+ }
1329
+ $form = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form );
1330
+ if ( ! empty ( $textareas ) ) {
1331
+ foreach ( $textareas as $textarea ) {
1332
+ $stripped = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $textarea );
1333
+ $form = str_replace( $stripped, $textarea, $form );
1334
+ }
1335
+ }
1336
+ return $form;
1337
+ }
1338
+
1339
+ /**
1340
+ * Login Dialog.
1341
+ *
1342
+ * Loads the login form for user login.
1343
+ *
1344
+ * @since 1.8
1345
+ * @since 3.1.4 Global $wpmem_regchk no longer needed.
1346
+ * @since 3.2.0 Moved to forms class, renamed do_login_form().
1347
+ *
1348
+ * @global object $post The WordPress Post object.
1349
+ * @global object $wpmem The WP_Members object.
1350
+ * @param string $page If the form is being displayed in place of blocked content. Default: page.
1351
+ * @param string $redirect_to Redirect URL. Default: null.
1352
+ * @param string $show If the form is being displayed in place of blocked content. Default: show.
1353
+ * @return string $str The generated html for the login form.
1354
+ */
1355
+ function do_login_form( $page = "page", $redirect_to = null, $show = 'show' ) {
1356
+
1357
+ global $post, $wpmem;
1358
+
1359
+ $str = '';
1360
+
1361
+ if ( $page == "page" ) {
1362
+
1363
+ if ( $wpmem->regchk != "success" ) {
1364
+
1365
+ $dialogs = get_option( 'wpmembers_dialogs' );
1366
+
1367
+ // This shown above blocked content.
1368
+ $msg = $wpmem->get_text( 'restricted_msg' );
1369
+ $msg = ( $dialogs['restricted_msg'] == $msg ) ? $msg : __( stripslashes( $dialogs['restricted_msg'] ), 'wp-members' );
1370
+ $str = '<div id="wpmem_restricted_msg"><p>' . $msg . '</p></div>';
1371
+
1372
+ /**
1373
+ * Filter the post restricted message.
1374
+ *
1375
+ * @since 2.7.3
1376
+ * @since 3.2.0 Added raw message string and HTML as separate params.
1377
+ *
1378
+ * @param string $str The post restricted message with HTML.
1379
+ * @param string $msg The raw message string.
1380
+ * @param string The 'before' HTML wrapper.
1381
+ * @param string The 'after' HTML wrapper.
1382
+ */
1383
+ $str = apply_filters( 'wpmem_restricted_msg', $str, $msg, '<div id="wpmem_restricted_msg"><p>', '</p></div>' );
1384
+
1385
+ }
1386
+ }
1387
+
1388
+ // Create the default inputs.
1389
+ $default_inputs = array(
1390
+ array(
1391
+ 'name' => $wpmem->get_text( 'login_username' ),
1392
+ 'type' => 'text',
1393
+ 'tag' => 'log',
1394
+ 'class' => 'username',
1395
+ 'div' => 'div_text',
1396
+ ),
1397
+ array(
1398
+ 'name' => $wpmem->get_text( 'login_password' ),
1399
+ 'type' => 'password',
1400
+ 'tag' => 'pwd',
1401
+ 'class' => 'password',
1402
+ 'div' => 'div_text',
1403
+ ),
1404
+ );
1405
+
1406
+ /**
1407
+ * Filter the array of login form fields.
1408
+ *
1409
+ * @since 2.9.0
1410
+ *
1411
+ * @param array $default_inputs An array matching the elements used by default.
1412
+ */
1413
+ $default_inputs = apply_filters( 'wpmem_inc_login_inputs', $default_inputs );
1414
+
1415
+ $defaults = array(
1416
+ 'heading' => $wpmem->get_text( 'login_heading' ),
1417
+ 'action' => 'login',
1418
+ 'button_text' => $wpmem->get_text( 'login_button' ),
1419
+ 'inputs' => $default_inputs,
1420
+ 'redirect_to' => $redirect_to,
1421
+ );
1422
+
1423
+ /**
1424
+ * Filter the arguments to override login form defaults.
1425
+ *
1426
+ * @since 2.9.0
1427
+ *
1428
+ * @param array $args An array of arguments to use. Default null.
1429
+ */
1430
+ $args = apply_filters( 'wpmem_inc_login_args', '' );
1431
+
1432
+ $arr = wp_parse_args( $args, $defaults );
1433
+
1434
+ $str = ( $show == 'show' ) ? $str . wpmem_login_form( $page, $arr ) : $str;
1435
+
1436
+ return $str;
1437
+ }
1438
+
1439
+ /**
1440
+ * Change Password Dialog.
1441
+ *
1442
+ * Loads the form for changing password.
1443
+ *
1444
+ * @since 2.0.0
1445
+ * @since 3.2.0 Moved to forms class, renamed do_changepassword_form().
1446
+ *
1447
+ * @global object $wpmem The WP_Members object.
1448
+ * @return string $str The generated html for the change password form.
1449
+ */
1450
+ function do_changepassword_form() {
1451
+
1452
+ global $wpmem;
1453
+
1454
+ // create the default inputs
1455
+ $default_inputs = array(
1456
+ array(
1457
+ 'name' => $wpmem->get_text( 'pwdchg_password1' ),
1458
+ 'type' => 'password',
1459
+ 'tag' => 'pass1',
1460
+ 'class' => 'password',
1461
+ 'div' => 'div_text',
1462
+ ),
1463
+ array(
1464
+ 'name' => $wpmem->get_text( 'pwdchg_password2' ),
1465
+ 'type' => 'password',
1466
+ 'tag' => 'pass2',
1467
+ 'class' => 'password',
1468
+ 'div' => 'div_text',
1469
+ ),
1470
+ );
1471
+
1472
+ /**
1473
+ * Filter the array of change password form fields.
1474
+ *
1475
+ * @since 2.9.0
1476
+ *
1477
+ * @param array $default_inputs An array matching the elements used by default.
1478
+ */
1479
+ $default_inputs = apply_filters( 'wpmem_inc_changepassword_inputs', $default_inputs );
1480
+
1481
+ $defaults = array(
1482
+ 'heading' => $wpmem->get_text( 'pwdchg_heading' ),
1483
+ 'action' => 'pwdchange',
1484
+ 'button_text' => $wpmem->get_text( 'pwdchg_button' ),
1485
+ 'inputs' => $default_inputs,
1486
+ );
1487
+
1488
+ /**
1489
+ * Filter the arguments to override change password form defaults.
1490
+ *
1491
+ * @since 2.9.0
1492
+ *
1493
+ * @param array $args An array of arguments to use. Default null.
1494
+ */
1495
+ $args = apply_filters( 'wpmem_inc_changepassword_args', '' );
1496
+
1497
+ $arr = wp_parse_args( $args, $defaults );
1498
+
1499
+ $str = wpmem_login_form( 'page', $arr );
1500
+
1501
+ return $str;
1502
+ }
1503
+
1504
+ /**
1505
+ * Reset Password Dialog.
1506
+ *
1507
+ * Loads the form for resetting password.
1508
+ *
1509
+ * @since 2.1.0
1510
+ * @since 3.2.0 Moved to forms class, renamed do_resetpassword_form().
1511
+ *
1512
+ * @global object $wpmem The WP_Members object.
1513
+ * @return string $str The generated html fo the reset password form.
1514
+ */
1515
+ function do_resetpassword_form() {
1516
+
1517
+ global $wpmem;
1518
+
1519
+ // Create the default inputs.
1520
+ $default_inputs = array(
1521
+ array(
1522
+ 'name' => $wpmem->get_text( 'pwdreset_username' ),
1523
+ 'type' => 'text',
1524
+ 'tag' => 'user',
1525
+ 'class' => 'username',
1526
+ 'div' => 'div_text',
1527
+ ),
1528
+ array(
1529
+ 'name' => $wpmem->get_text( 'pwdreset_email' ),
1530
+ 'type' => 'text',
1531
+ 'tag' => 'email',
1532
+ 'class' => 'text',
1533
+ 'div' => 'div_text',
1534
+ ),
1535
+ );
1536
+
1537
+ /**
1538
+ * Filter the array of reset password form fields.
1539
+ *
1540
+ * @since 2.9.0
1541
+ *
1542
+ * @param array $default_inputs An array matching the elements used by default.
1543
+ */
1544
+ $default_inputs = apply_filters( 'wpmem_inc_resetpassword_inputs', $default_inputs );
1545
+
1546
+ $defaults = array(
1547
+ 'heading' => $wpmem->get_text( 'pwdreset_heading' ),
1548
+ 'action' => 'pwdreset',
1549
+ 'button_text' => $wpmem->get_text( 'pwdreset_button' ),
1550
+ 'inputs' => $default_inputs,
1551
+ );
1552
+
1553
+ /**
1554
+ * Filter the arguments to override reset password form defaults.
1555
+ *
1556
+ * @since 2.9.0
1557
+ *
1558
+ * @param array $args An array of arguments to use. Default null.
1559
+ */
1560
+ $args = apply_filters( 'wpmem_inc_resetpassword_args', '' );
1561
+
1562
+ $arr = wp_parse_args( $args, $defaults );
1563
+
1564
+ $str = wpmem_login_form( 'page', $arr );
1565
+
1566
+ return $str;
1567
+ }
1568
+
1569
+ /**
1570
+ * Forgot Username Form.
1571
+ *
1572
+ * Loads the form for retrieving a username.
1573
+ *
1574
+ * @since 3.0.8
1575
+ * @since 3.2.0 Moved to forms class, renamed do_forgotusername_form().
1576
+ *
1577
+ * @global object $wpmem The WP_Members object class.
1578
+ * @return string $str The generated html for the forgot username form.
1579
+ */
1580
+ function do_forgotusername_form() {
1581
+
1582
+ global $wpmem;
1583
+
1584
+ // create the default inputs
1585
+ $default_inputs = array(
1586
+ array(
1587
+ 'name' => $wpmem->get_text( 'username_email' ),
1588
+ 'type' => 'text',
1589
+ 'tag' => 'user_email',
1590
+ 'class' => 'username',
1591
+ 'div' => 'div_text',
1592
+ ),
1593
+ );
1594
+
1595
+ /**
1596
+ * Filter the array of forgot username form fields.
1597
+ *
1598
+ * @since 2.9.0
1599
+ *
1600
+ * @param array $default_inputs An array matching the elements used by default.
1601
+ */
1602
+ $default_inputs = apply_filters( 'wpmem_inc_forgotusername_inputs', $default_inputs );
1603
+
1604
+ $defaults = array(
1605
+ 'heading' => $wpmem->get_text( 'username_heading' ),
1606
+ 'action' => 'getusername',
1607
+ 'button_text' => $wpmem->get_text( 'username_button' ),
1608
+ 'inputs' => $default_inputs,
1609
+ );
1610
+
1611
+ /**
1612
+ * Filter the arguments to override change password form defaults.
1613
+ *
1614
+ * @since
1615
+ *
1616
+ * @param array $args An array of arguments to use. Default null.
1617
+ */
1618
+ $args = apply_filters( 'wpmem_inc_forgotusername_args', '' );
1619
+
1620
+ $arr = wp_parse_args( $args, $defaults );
1621
+
1622
+ $str = wpmem_login_form( 'page', $arr );
1623
+
1624
+ return $str;
1625
+ }
1626
+
1627
+
1628
  } // End of WP_Members_Forms class.
inc/class-wp-members-menus.php CHANGED
@@ -67,7 +67,18 @@ class WP_Members_Menus {
67
  $theme_loc = $args['theme_location'] . '_wpmem_loggedin';
68
  $menu_locs = get_nav_menu_locations();
69
 
70
- $serve_menu = apply_filters( 'wpmem_lim_serve_menu', true );
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  if ( is_user_logged_in( $menu_locs )
73
  && ! empty( $args['theme_location'] )
67
  $theme_loc = $args['theme_location'] . '_wpmem_loggedin';
68
  $menu_locs = get_nav_menu_locations();
69
 
70
+ /**
71
+ * Filter the served menu.
72
+ *
73
+ * @since 3.2.6
74
+ * @todo Determine what extra parameters to pass and how (then document them).
75
+ *
76
+ * @param array boolean
77
+ * @param string $theme_loc
78
+ * @param $menu_locs
79
+ * @param array $args
80
+ */
81
+ $serve_menu = apply_filters( 'wpmem_serve_menu', true, $theme_loc, $menu_locs, $args );
82
 
83
  if ( is_user_logged_in( $menu_locs )
84
  && ! empty( $args['theme_location'] )
inc/class-wp-members-products.php CHANGED
@@ -50,7 +50,23 @@ class WP_Members_Products {
50
  *
51
  * @since 3.2.0
52
  * @access public
53
- * @var array
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  */
55
  public $products = array();
56
 
@@ -59,7 +75,11 @@ class WP_Members_Products {
59
  *
60
  * @since 3.2.4
61
  * @access public
62
- * @var array
 
 
 
 
63
  */
64
  public $product_by_id = array();
65
 
@@ -68,7 +88,7 @@ class WP_Members_Products {
68
  *
69
  * @since 3.2.0
70
  *
71
- * @global object $wpmem
72
  */
73
  function __construct() {
74
 
@@ -81,10 +101,14 @@ class WP_Members_Products {
81
  * Loads product settings.
82
  *
83
  * @since 3.2.0
 
 
84
  */
85
  function load_products() {
86
  global $wpdb;
87
- $sql = "SELECT ID, post_title, post_name FROM " . $wpdb->prefix . "posts WHERE post_type = 'wpmem_product' AND post_status = 'publish';";
 
 
88
  $result = $wpdb->get_results( $sql );
89
  foreach ( $result as $plan ) {
90
  $this->product_by_id[ $plan->ID ] = $plan->post_name;
@@ -107,7 +131,11 @@ class WP_Members_Products {
107
  * @since 3.2.4
108
  *
109
  * @param integer $post_id
110
- * @return array $products
 
 
 
 
111
  */
112
  function get_post_products( $post_id ) {
113
  $products = get_post_meta( $post_id, $this->post_meta, true );
@@ -120,8 +148,8 @@ class WP_Members_Products {
120
  * @since 3.2.0
121
  * @since 3.2.2 Merged check_product_access() logic for better messaging.
122
  *
123
- * @global object $post
124
- * @global object $wpmem
125
  * @param string $content
126
  * @return string $content
127
  */
@@ -153,7 +181,11 @@ class WP_Members_Products {
153
  * @since 3.2.3
154
  *
155
  * @param string The message.
156
- * @param array $post_products Post products array.
 
 
 
 
157
  */
158
  $content = ( $access ) ? $content : apply_filters( 'wpmem_product_restricted_msg', $wpmem->get_text( 'product_restricted' ), $post_products );
159
 
@@ -170,6 +202,8 @@ class WP_Members_Products {
170
  * Register Membership Plans Custom Post Type
171
  *
172
  * @since 3.2.0
 
 
173
  */
174
  function add_cpt() {
175
 
50
  *
51
  * @since 3.2.0
52
  * @access public
53
+ * @var array {
54
+ * Array of membership product information.
55
+ *
56
+ * @type array $product_slug {
57
+ * Array of membership product settings.
58
+ *
59
+ * @type string $title The product title (user view).
60
+ * @type string $role User role, if a role is required.
61
+ * @type string $name The product slug.
62
+ * @type string $default
63
+ * @type array $expires {
64
+ * If the membership has expiration periods.
65
+ *
66
+ * $type string number|period Number of periods|Period (year/month/week/day).
67
+ * }
68
+ * }
69
+ * }
70
  */
71
  public $products = array();
72
 
75
  *
76
  * @since 3.2.4
77
  * @access public
78
+ * @var array {
79
+ * Array of membership products keyed by CPT ID.
80
+ *
81
+ * @type string $ID The membership product slug.
82
+ * }
83
  */
84
  public $product_by_id = array();
85
 
88
  *
89
  * @since 3.2.0
90
  *
91
+ * @global object $wpmem The WP_Members object class.
92
  */
93
  function __construct() {
94
 
101
  * Loads product settings.
102
  *
103
  * @since 3.2.0
104
+ *
105
+ * @global object $wpdb The WPDB object class.
106
  */
107
  function load_products() {
108
  global $wpdb;
109
+ $sql = "SELECT ID, post_title, post_name FROM "
110
+ . $wpdb->prefix
111
+ . "posts WHERE post_type = 'wpmem_product' AND post_status = 'publish';";
112
  $result = $wpdb->get_results( $sql );
113
  foreach ( $result as $plan ) {
114
  $this->product_by_id[ $plan->ID ] = $plan->post_name;
131
  * @since 3.2.4
132
  *
133
  * @param integer $post_id
134
+ * @return array $products {
135
+ * Membership product slugs the post is restricted to.
136
+ *
137
+ * @type string $slug
138
+ * }
139
  */
140
  function get_post_products( $post_id ) {
141
  $products = get_post_meta( $post_id, $this->post_meta, true );
148
  * @since 3.2.0
149
  * @since 3.2.2 Merged check_product_access() logic for better messaging.
150
  *
151
+ * @global object $post The WordPress Post object.
152
+ * @global object $wpmem The WP_Members object class.
153
  * @param string $content
154
  * @return string $content
155
  */
181
  * @since 3.2.3
182
  *
183
  * @param string The message.
184
+ * @param array $post_products {
185
+ * Membership product slugs the post is restricted to.
186
+ *
187
+ * @type string $slug
188
+ * }
189
  */
190
  $content = ( $access ) ? $content : apply_filters( 'wpmem_product_restricted_msg', $wpmem->get_text( 'product_restricted' ), $post_products );
191
 
202
  * Register Membership Plans Custom Post Type
203
  *
204
  * @since 3.2.0
205
+ *
206
+ * @global object $wpmem The WP_Members object class.
207
  */
208
  function add_cpt() {
209
 
inc/class-wp-members-shortcodes.php CHANGED
@@ -561,65 +561,71 @@ class WP_Members_Shortcodes {
561
 
562
  $user_info_field = ( isset( $field ) && is_object( $user_info ) ) ? $user_info->{$field} : '';
563
  $result = false;
564
-
565
- // Handle select and radio groups (have single selections).
566
- if ( 'select' == $field_type || 'radio' == $field_type ) {
567
- $result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info_field : $fields[ $field ]['options'][ $user_info_field ];
568
- }
569
-
570
- // Handle multiple select and multiple checkbox (have multiple selections).
571
- if ( 'multiselect' == $field_type || 'multicheckbox' == $field_type ) {
572
- if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
573
- $result = $user_info_field;
574
- } else {
575
- $saved_vals = explode( $fields[ $field ]['delimiter'], $user_info_field );
576
- $result = ''; $x = 1;
577
- foreach ( $saved_vals as $value ) {
578
- $result.= ( $x > 1 ) ? ', ' : ''; $x++;
579
- $result.= $fields[ $field ]['options'][ $value ];
 
 
 
 
 
 
580
  }
581
- }
582
- }
583
-
584
- // Handle file/image fields.
585
- if ( isset( $field_type ) && ( 'file' == $field_type || 'image' == $field_type ) ) {
586
- if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
587
- $result = $user_info_field;
588
- } else {
589
- if ( 'file' == $field_type ) {
590
- $attachment_url = wp_get_attachment_url( $user_info_field );
591
- $result = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '">' . get_the_title( $user_info_field ) . '</a>' : '';
592
  } else {
593
- $size = 'thumbnail';
594
- if ( isset( $atts['size'] ) ) {
595
- $sizes = array( 'thumbnail', 'medium', 'large', 'full' );
596
- $size = ( ! in_array( $atts['size'], $sizes ) ) ? explode( ",", $atts['size'] ) : $atts['size'];
 
 
 
 
 
 
 
597
  }
598
- $image = wp_get_attachment_image_src( $user_info_field, $size );
599
- $result = ( $image ) ? '<img src="' . esc_url( $image[0] ) . '" width="' . esc_attr( $image[1] ) . '" height="' . esc_attr( $image[2] ) . '" />' : '';
600
  }
601
- }
602
- return do_shortcode( $result );
603
- }
604
-
605
- // Handle line breaks for textarea fields
606
- if ( isset( $field_type ) && 'textarea' == $field_type ) {
607
- $result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info_field : nl2br( $user_info_field );
608
- }
609
-
610
- // Handle date fields.
611
- if ( isset( $field_type ) && 'date' == $field_type ) {
612
- if ( isset( $atts['format'] ) ) {
613
- // Formats date: https://secure.php.net/manual/en/function.date.php
614
- $result = ( '' != $user_info_field ) ? date( $atts['format'], strtotime( $user_info_field ) ) : '';
615
- } else {
616
- // Formats date to whatever the WP setting is.
617
- $result = ( '' != $user_info_field ) ? date_i18n( get_option( 'date_format' ), strtotime( $user_info_field ) ) : '';
618
- }
 
 
 
619
  }
620
-
621
- // Handle all other fields.
622
- $result = ( ! $result ) ? $user_info_field : $result;
623
 
624
  // Remove underscores from value if requested (default: on).
625
  if ( isset( $atts['underscores'] ) && 'off' == $atts['underscores'] && $user_info ) {
@@ -634,6 +640,7 @@ class WP_Members_Shortcodes {
634
  // Display field label?
635
  $content = ( isset( $atts['label'] ) && ( true == $atts['label'] ) ) ? $fields[ $field ]['label'] . ": " . $content : $content;
636
  }
 
637
  /**
638
  * Filters the field shortcode before returning value.
639
  *
561
 
562
  $user_info_field = ( isset( $field ) && is_object( $user_info ) ) ? $user_info->{$field} : '';
563
  $result = false;
564
+
565
+ // Handle each field type.
566
+ switch ( $field_type ) {
567
+
568
+ // Select and radio groups have single selections.
569
+ case 'select':
570
+ case 'radio':
571
+ $result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info_field : $fields[ $field ]['options'][ $user_info_field ];
572
+ break;
573
+
574
+ // Multiple select and multiple checkbox have multiple selections.
575
+ case 'multiselect':
576
+ case 'multicheckbox':
577
+ if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
578
+ $result = $user_info_field;
579
+ } else {
580
+ $saved_vals = explode( $fields[ $field ]['delimiter'], $user_info_field );
581
+ $result = ''; $x = 1;
582
+ foreach ( $saved_vals as $value ) {
583
+ $result.= ( $x > 1 ) ? ', ' : ''; $x++;
584
+ $result.= $fields[ $field ]['options'][ $value ];
585
+ }
586
  }
587
+ break;
588
+
589
+ case 'file':
590
+ case 'image':
591
+ if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
592
+ $result = $user_info_field;
 
 
 
 
 
593
  } else {
594
+ if ( 'file' == $field_type ) {
595
+ $attachment_url = wp_get_attachment_url( $user_info_field );
596
+ $result = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '">' . get_the_title( $user_info_field ) . '</a>' : '';
597
+ } else {
598
+ $size = 'thumbnail';
599
+ if ( isset( $atts['size'] ) ) {
600
+ $sizes = array( 'thumbnail', 'medium', 'large', 'full' );
601
+ $size = ( ! in_array( $atts['size'], $sizes ) ) ? explode( ",", $atts['size'] ) : $atts['size'];
602
+ }
603
+ $image = wp_get_attachment_image_src( $user_info_field, $size );
604
+ $result = ( $image ) ? '<img src="' . esc_url( $image[0] ) . '" width="' . esc_attr( $image[1] ) . '" height="' . esc_attr( $image[2] ) . '" />' : '';
605
  }
 
 
606
  }
607
+ break;
608
+
609
+ case 'textarea':
610
+ // Handle line breaks for textarea fields
611
+ $result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info_field : nl2br( $user_info_field );
612
+ break;
613
+
614
+ case 'date':
615
+ if ( isset( $atts['format'] ) ) {
616
+ // Formats date: https://secure.php.net/manual/en/function.date.php
617
+ $result = ( '' != $user_info_field ) ? date( $atts['format'], strtotime( $user_info_field ) ) : '';
618
+ } else {
619
+ // Formats date to whatever the WP setting is.
620
+ $result = ( '' != $user_info_field ) ? date_i18n( get_option( 'date_format' ), strtotime( $user_info_field ) ) : '';
621
+ }
622
+ break;
623
+
624
+ // Handle all other fields.
625
+ default:
626
+ $result = ( ! $result ) ? $user_info_field : $result;
627
+ break;
628
  }
 
 
 
629
 
630
  // Remove underscores from value if requested (default: on).
631
  if ( isset( $atts['underscores'] ) && 'off' == $atts['underscores'] && $user_info ) {
640
  // Display field label?
641
  $content = ( isset( $atts['label'] ) && ( true == $atts['label'] ) ) ? $fields[ $field ]['label'] . ": " . $content : $content;
642
  }
643
+
644
  /**
645
  * Filters the field shortcode before returning value.
646
  *
inc/class-wp-members-user-profile.php CHANGED
@@ -222,6 +222,19 @@ class WP_Members_User_Profile {
222
 
223
  </table><?php
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  }
226
 
227
  /**
222
 
223
  </table><?php
224
 
225
+ /**
226
+ * Fires after the user profile table.
227
+ *
228
+ * Action fires for the admin user edit ("wpmem_admin_after_profile_table")
229
+ * and the user profile edit ("wpmem_user_after_profile_table").
230
+ *
231
+ * @since 3.2.6
232
+ *
233
+ * @param int $user_id The user's ID.
234
+ * @param array $wpmem_fields The WP-Members fields.
235
+ */
236
+ do_action( 'wpmem_' . $display . '_after_profile_table', $user_id, $wpmem_fields );
237
+
238
  }
239
 
240
  /**
inc/class-wp-members-user.php CHANGED
@@ -153,6 +153,7 @@ class WP_Members_User {
153
  * User registration functions.
154
  *
155
  * @since 3.1.7
 
156
  *
157
  * @global object $wpmem
158
  * @param int $user_id
@@ -170,7 +171,12 @@ class WP_Members_User {
170
  // If the field is not excluded, update accordingly.
171
  if ( ! in_array( $meta_key, $wpmem->excluded_meta ) && ! in_array( $meta_key, $new_user_fields_meta ) ) {
172
  if ( $field['register'] && 'user_email' != $meta_key ) {
173
- update_user_meta( $user_id, $meta_key, $this->post_data[ $meta_key ] );
 
 
 
 
 
174
  }
175
  }
176
  }
@@ -280,6 +286,10 @@ class WP_Members_User {
280
  * @param string $args['pass1'] The user's new plain text password.
281
  */
282
  $is_error = apply_filters( 'wpmem_pwd_change_error', $is_error, $user_ID, $args['pass1'] );
 
 
 
 
283
  if ( $is_error ) {
284
  return $is_error;
285
  }
@@ -320,6 +330,9 @@ class WP_Members_User {
320
 
321
  } else {
322
 
 
 
 
323
  if ( username_exists( $arr['user'] ) ) {
324
  $user = get_user_by( 'login', $arr['user'] );
325
  if ( strtolower( $user->user_email ) !== strtolower( $arr['email'] ) || ( ( $wpmem->mod_reg == 1 ) && ( get_user_meta( $user->ID, 'active', true ) != 1 ) ) ) {
@@ -391,6 +404,7 @@ class WP_Members_User {
391
  * Handle user file uploads for registration and profile update.
392
  *
393
  * @since 3.1.8
 
394
  *
395
  * @param string $user_id
396
  * @param array $fields
@@ -404,6 +418,8 @@ class WP_Members_User {
404
  $file_post_id = $wpmem->forms->do_file_upload( $_FILES[ $meta_key ], $user_id );
405
  // Save the attachment ID as user meta.
406
  update_user_meta( $user_id, $meta_key, $file_post_id );
 
 
407
  }
408
  }
409
  }
@@ -416,20 +432,31 @@ class WP_Members_User {
416
  * in an array keyed by WP-Members field meta keys.
417
  *
418
  * @since 3.2.0
 
419
  *
420
- * @param mixed $user_id
421
- * @return array $user_fields
 
422
  */
423
- function user_data( $user_id = false ) {
424
- $fields = wpmem_fields();
425
  $user_id = ( $user_id ) ? $user_id : get_current_user_id();
426
- $user_data = get_userdata( $user_id );
427
- $excludes = array( 'first_name', 'last_name', 'description', 'nickname' );
428
- foreach ( $fields as $meta => $field ) {
429
- if ( $field['native'] == 1 && ! in_array( $meta, $excludes ) ) {
430
- $user_fields[ $meta ] = $user_data->data->$meta;
431
- } else {
432
- $user_fields[ $meta ] = get_user_meta( $user_id, $meta, true );
 
 
 
 
 
 
 
 
 
 
433
  }
434
  }
435
  return $user_fields;
@@ -561,12 +588,15 @@ class WP_Members_User {
561
  * Loads anything the user has access to.
562
  *
563
  * @since 3.2.0
 
564
  *
565
- * @param int $user_id
 
566
  */
567
  function get_user_products( $user_id = false ) {
568
- $user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
569
- return get_user_meta( $user_id, '_wpmem_products', true );
 
570
  }
571
 
572
  /**
@@ -577,11 +607,13 @@ class WP_Members_User {
577
  * set to "true" (which does not expire).
578
  *
579
  * @since 3.2.0
 
580
  *
581
  * @param string $product
582
  * @param int $user_id
 
583
  */
584
- function set_user_product( $product, $user_id = false ) {
585
 
586
  global $wpmem;
587
 
@@ -598,7 +630,11 @@ class WP_Members_User {
598
  if ( is_array( $expires ) ) {
599
  $add_date = explode( "|", $wpmem->membership->products[ $product ]['expires'][0] );
600
  $add = ( 1 < $add_date[0] ) ? $add_date[0] . " " . $add_date[1] . "s" : $add_date[0] . " " . $add_date[1];
601
- $user_products[ $product ] = ( isset( $user_products[ $product ] ) ) ? date( 'Y-m-d H:i:s', strtotime( $add, strtotime( $user_products[ $product ] ) ) ) : date( 'Y-m-d H:i:s', strtotime( $add ) );
 
 
 
 
602
  } else {
603
  $user_products[ $product ] = true;
604
  }
153
  * User registration functions.
154
  *
155
  * @since 3.1.7
156
+ * @since 3.2.6 Added handler for membership field type.
157
  *
158
  * @global object $wpmem
159
  * @param int $user_id
171
  // If the field is not excluded, update accordingly.
172
  if ( ! in_array( $meta_key, $wpmem->excluded_meta ) && ! in_array( $meta_key, $new_user_fields_meta ) ) {
173
  if ( $field['register'] && 'user_email' != $meta_key ) {
174
+ // Assign memberships, if applicable.
175
+ if ( 'membership' == $field['type'] && 1 == $wpmem->enable_products ) {
176
+ wpmem_set_user_product( $this->post_data[ $meta_key ], $user_id );
177
+ } else {
178
+ update_user_meta( $user_id, $meta_key, $this->post_data[ $meta_key ] );
179
+ }
180
  }
181
  }
182
  }
286
  * @param string $args['pass1'] The user's new plain text password.
287
  */
288
  $is_error = apply_filters( 'wpmem_pwd_change_error', $is_error, $user_ID, $args['pass1'] );
289
+ // User must be logged in.
290
+ $is_error = ( ! is_user_logged_in() ) ? "loggedin" : $is_error;
291
+ // Verify nonce.
292
+ $is_error = ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'wpmem_login_nonce' ) ) ? "reg_generic" : $is_error;
293
  if ( $is_error ) {
294
  return $is_error;
295
  }
330
 
331
  } else {
332
 
333
+ if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'wpmem_login_nonce' ) ) {
334
+ return "reg_generic";
335
+ }
336
  if ( username_exists( $arr['user'] ) ) {
337
  $user = get_user_by( 'login', $arr['user'] );
338
  if ( strtolower( $user->user_email ) !== strtolower( $arr['email'] ) || ( ( $wpmem->mod_reg == 1 ) && ( get_user_meta( $user->ID, 'active', true ) != 1 ) ) ) {
404
  * Handle user file uploads for registration and profile update.
405
  *
406
  * @since 3.1.8
407
+ * @since 3.2.6 Add file's post ID to $this->post_data.
408
  *
409
  * @param string $user_id
410
  * @param array $fields
418
  $file_post_id = $wpmem->forms->do_file_upload( $_FILES[ $meta_key ], $user_id );
419
  // Save the attachment ID as user meta.
420
  update_user_meta( $user_id, $meta_key, $file_post_id );
421
+ // Add attachement ID to post data array.
422
+ $this->post_data[ $meta_key ] = $file_post_id;
423
  }
424
  }
425
  }
432
  * in an array keyed by WP-Members field meta keys.
433
  *
434
  * @since 3.2.0
435
+ * @since 3.2.6 Added option for "all" fields (default:false).
436
  *
437
+ * @param string $user_id optional (defaults to current user)
438
+ * @param string $all optional (default to false)
439
+ * @return array $user_fields
440
  */
441
+ function user_data( $user_id = false, $all = false ) {
 
442
  $user_id = ( $user_id ) ? $user_id : get_current_user_id();
443
+ if ( true == $all ) {
444
+ $user_info = get_user_meta( $user_id );
445
+ foreach( $user_info as $key => $value ) {
446
+ $formatted = maybe_unserialize( $value[0] );
447
+ $user_fields[ $key ] = $formatted;
448
+ }
449
+ } else {
450
+ $fields = wpmem_fields();
451
+ $user_data = get_userdata( $user_id );
452
+ $excludes = array( 'first_name', 'last_name', 'description', 'nickname' );
453
+ foreach ( $fields as $meta => $field ) {
454
+ $meta = ( 'username' == $meta ) ? 'user_login' : $meta;
455
+ if ( $field['native'] == 1 && ! in_array( $meta, $excludes ) ) {
456
+ $user_fields[ $meta ] = $user_data->data->{$meta};
457
+ } else {
458
+ $user_fields[ $meta ] = get_user_meta( $user_id, $meta, true );
459
+ }
460
  }
461
  }
462
  return $user_fields;
588
  * Loads anything the user has access to.
589
  *
590
  * @since 3.2.0
591
+ * @since 3.2.6 Updated to return empty array if no products exist for this user.
592
  *
593
+ * @param int $user_id
594
+ * @return array $products
595
  */
596
  function get_user_products( $user_id = false ) {
597
+ $user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
598
+ $products = get_user_meta( $user_id, '_wpmem_products', true );
599
+ return ( $products ) ? $products : array();
600
  }
601
 
602
  /**
607
  * set to "true" (which does not expire).
608
  *
609
  * @since 3.2.0
610
+ * @since 3.2.6 Added $date to set a specific expiration date.
611
  *
612
  * @param string $product
613
  * @param int $user_id
614
+ * @param string $set_date
615
  */
616
+ function set_user_product( $product, $user_id = false, $set_date = false ) {
617
 
618
  global $wpmem;
619
 
630
  if ( is_array( $expires ) ) {
631
  $add_date = explode( "|", $wpmem->membership->products[ $product ]['expires'][0] );
632
  $add = ( 1 < $add_date[0] ) ? $add_date[0] . " " . $add_date[1] . "s" : $add_date[0] . " " . $add_date[1];
633
+ if ( $set_date ) {
634
+ $user_products[ $product ] = date( 'Y-m-d H:i:s', strtotime( $set_date ) );
635
+ } else {
636
+ $user_products[ $product ] = ( isset( $user_products[ $product ] ) ) ? date( 'Y-m-d H:i:s', strtotime( $add, strtotime( $user_products[ $product ] ) ) ) : date( 'Y-m-d H:i:s', strtotime( $add ) );
637
+ }
638
  } else {
639
  $user_products[ $product ] = true;
640
  }
inc/class-wp-members.php CHANGED
@@ -325,10 +325,13 @@ class WP_Members {
325
  add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
326
  add_action( 'init', array( $this, 'load_textdomain' ) ); //add_action( 'plugins_loaded', 'wpmem_load_textdomain' );
327
  add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
328
- add_action( 'wpmem_pwd_change', array( $this->user, 'set_password' ), 9, 2 );
329
- add_action( 'wpmem_pwd_change', array( $this->user, 'set_as_logged_in' ), 10 );
330
  add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ) );
331
  add_action( 'customize_register', array( $this, 'customizer_settings' ) );
 
 
 
 
 
332
 
333
  // Add filters.
334
  add_filter( 'the_content', array( $this, 'do_securify' ), 99 );
@@ -942,7 +945,7 @@ class WP_Members {
942
  foreach ( $hidden as $post_id ) {
943
  if ( 1 == get_post_meta( $post_id, $this->membership->post_stem . $key, true ) ) {
944
  $hidden_key = array_search( $post_id, $hidden );
945
- unset( $hidden[ $hidden_key ] );
946
  }
947
  }
948
  }
@@ -1202,7 +1205,6 @@ class WP_Members {
1202
  */
1203
  $benign_strings = array(
1204
  __( 'No fields selected for deletion', 'wp-members' ),
1205
- __( 'Username or Email', 'wp-members' ),
1206
  __( 'You are not logged in.', 'wp-members' ), // Technically removed 3.5
1207
  );
1208
 
@@ -1210,7 +1212,7 @@ class WP_Members {
1210
 
1211
  // Login form.
1212
  'login_heading' => __( 'Existing Users Log In', 'wp-members' ),
1213
- 'login_username' => __( 'Username', 'wp-members' ),
1214
  'login_password' => __( 'Password', 'wp-members' ),
1215
  'login_button' => __( 'Log In', 'wp-members' ),
1216
  'remember_me' => __( 'Remember Me', 'wp-members' ),
@@ -1297,14 +1299,19 @@ class WP_Members {
1297
 
1298
  // Default Dialogs.
1299
  'restricted_msg' => __( "This content is restricted to site members. If you are an existing user, please log in. New users may register below.", 'wp-members' ),
 
 
 
1300
  'user' => __( "Sorry, that username is taken, please try another.", 'wp-members' ),
1301
  'email' => __( "Sorry, that email address already has an account.<br />Please try another.", 'wp-members' ),
1302
- 'success' => __( "Congratulations! Your registration was successful.<br /><br />You may now log in using the password that was emailed to you.", 'wp-members' ),
1303
  'editsuccess' => __( "Your information was updated!", 'wp-members' ),
 
 
1304
  'pwdchangerr' => __( "Passwords did not match.<br /><br />Please try again.", 'wp-members' ),
1305
  'pwdchangesuccess' => __( "Password successfully changed!", 'wp-members' ),
1306
  'pwdreseterr' => __( "Either the username or email address do not exist in our records.", 'wp-members' ),
1307
  'pwdresetsuccess' => __( "Password successfully reset!<br /><br />An email containing a new password has been sent to the email address on file for your account.", 'wp-members' ),
 
1308
  'product_restricted' => __( "Sorry, you do not have access to this content.", 'wp-members' ),
1309
 
1310
  ); // End of $defaults array.
325
  add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
326
  add_action( 'init', array( $this, 'load_textdomain' ) ); //add_action( 'plugins_loaded', 'wpmem_load_textdomain' );
327
  add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
 
 
328
  add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ) );
329
  add_action( 'customize_register', array( $this, 'customizer_settings' ) );
330
+
331
+ if ( is_user_logged_in() ) {
332
+ add_action( 'wpmem_pwd_change', array( $this->user, 'set_password' ), 9, 2 );
333
+ add_action( 'wpmem_pwd_change', array( $this->user, 'set_as_logged_in' ), 10 );
334
+ }
335
 
336
  // Add filters.
337
  add_filter( 'the_content', array( $this, 'do_securify' ), 99 );
945
  foreach ( $hidden as $post_id ) {
946
  if ( 1 == get_post_meta( $post_id, $this->membership->post_stem . $key, true ) ) {
947
  $hidden_key = array_search( $post_id, $hidden );
948
+ unset( $hidden[ $hidden_key ] );
949
  }
950
  }
951
  }
1205
  */
1206
  $benign_strings = array(
1207
  __( 'No fields selected for deletion', 'wp-members' ),
 
1208
  __( 'You are not logged in.', 'wp-members' ), // Technically removed 3.5
1209
  );
1210
 
1212
 
1213
  // Login form.
1214
  'login_heading' => __( 'Existing Users Log In', 'wp-members' ),
1215
+ 'login_username' => __( 'Username or Email', 'wp-members' ),
1216
  'login_password' => __( 'Password', 'wp-members' ),
1217
  'login_button' => __( 'Log In', 'wp-members' ),
1218
  'remember_me' => __( 'Remember Me', 'wp-members' ),
1299
 
1300
  // Default Dialogs.
1301
  'restricted_msg' => __( "This content is restricted to site members. If you are an existing user, please log in. New users may register below.", 'wp-members' ),
1302
+ 'success' => __( "Congratulations! Your registration was successful.<br /><br />You may now log in using the password that was emailed to you.", 'wp-members' ),
1303
+
1304
+ // @todo Under consideration for removal from the Dialogs tab.
1305
  'user' => __( "Sorry, that username is taken, please try another.", 'wp-members' ),
1306
  'email' => __( "Sorry, that email address already has an account.<br />Please try another.", 'wp-members' ),
 
1307
  'editsuccess' => __( "Your information was updated!", 'wp-members' ),
1308
+
1309
+ // @todo These are defaults and are under consideration for removal from the dialogs tab, possibly as we change the password reset to a link based process.
1310
  'pwdchangerr' => __( "Passwords did not match.<br /><br />Please try again.", 'wp-members' ),
1311
  'pwdchangesuccess' => __( "Password successfully changed!", 'wp-members' ),
1312
  'pwdreseterr' => __( "Either the username or email address do not exist in our records.", 'wp-members' ),
1313
  'pwdresetsuccess' => __( "Password successfully reset!<br /><br />An email containing a new password has been sent to the email address on file for your account.", 'wp-members' ),
1314
+
1315
  'product_restricted' => __( "Sorry, you do not have access to this content.", 'wp-members' ),
1316
 
1317
  ); // End of $defaults array.
inc/dialogs.php CHANGED
@@ -402,6 +402,7 @@ if ( ! function_exists( 'wpmem_page_pwd_reset' ) ):
402
  * password forms for page=password shortcode.
403
  *
404
  * @since 2.7.6
 
405
  *
406
  * @global object $wpmem
407
  * @param string $wpmem_regchk
@@ -416,23 +417,16 @@ function wpmem_page_pwd_reset( $wpmem_regchk, $content ) {
416
 
417
  switch ( $wpmem_regchk ) {
418
 
419
- case "pwdchangempty":
420
- $content = wpmem_inc_regmessage( $wpmem_regchk, $wpmem->get_text( 'pwdchangempty' ) );
421
- $content = $content . wpmem_inc_changepassword();
422
- break;
423
-
424
- case "pwdchangerr":
425
- $content = wpmem_inc_regmessage( $wpmem_regchk );
426
- $content = $content . wpmem_inc_changepassword();
427
- break;
428
-
429
- case "pwdchangesuccess":
430
- $content = $content . wpmem_inc_regmessage( $wpmem_regchk );
431
- break;
432
 
433
- default:
434
- $content = $content . wpmem_inc_changepassword();
435
- break;
 
 
 
436
  }
437
 
438
  } else {
@@ -445,22 +439,18 @@ function wpmem_page_pwd_reset( $wpmem_regchk, $content ) {
445
  } else {
446
 
447
  switch( $wpmem_regchk ) {
448
-
449
- case "pwdreseterr":
450
- $content = $content
451
- . wpmem_inc_regmessage( $wpmem_regchk )
452
- . wpmem_inc_resetpassword();
453
- $wpmem_regchk = ''; // Clear regchk.
454
- break;
455
-
456
- case "pwdresetsuccess":
457
- $content = $content . wpmem_inc_regmessage( $wpmem_regchk );
458
- $wpmem_regchk = ''; // Clear regchk.
459
- break;
460
-
461
- default:
462
- $content = $content . wpmem_inc_resetpassword();
463
- break;
464
  }
465
 
466
  }
402
  * password forms for page=password shortcode.
403
  *
404
  * @since 2.7.6
405
+ * @since 3.2.6 Added nonce validation.
406
  *
407
  * @global object $wpmem
408
  * @param string $wpmem_regchk
417
 
418
  switch ( $wpmem_regchk ) {
419
 
420
+ case "pwdchangesuccess":
421
+ $content = $content . wpmem_inc_regmessage( $wpmem_regchk );
422
+ break;
 
 
 
 
 
 
 
 
 
 
423
 
424
+ default:
425
+ if ( isset( $wpmem_regchk ) && '' != $wpmem_regchk ) {
426
+ $content .= wpmem_inc_regmessage( $wpmem_regchk, $wpmem->get_text( $wpmem_regchk ) );
427
+ }
428
+ $content = $content . wpmem_inc_changepassword();
429
+ break;
430
  }
431
 
432
  } else {
439
  } else {
440
 
441
  switch( $wpmem_regchk ) {
442
+
443
+ case "pwdresetsuccess":
444
+ $content = $content . wpmem_inc_regmessage( $wpmem_regchk );
445
+ $wpmem_regchk = ''; // Clear regchk.
446
+ break;
447
+
448
+ default:
449
+ if ( isset( $wpmem_regchk ) && '' != $wpmem_regchk ) {
450
+ $content = wpmem_inc_regmessage( $wpmem_regchk, $wpmem->get_text( $wpmem_regchk ) );
451
+ }
452
+ $content = $content . wpmem_inc_resetpassword();
453
+ break;
 
 
 
 
454
  }
455
 
456
  }
inc/register.php CHANGED
@@ -140,7 +140,7 @@ function wpmem_registration( $tag ) {
140
  }
141
  } else {
142
  // If the required field is any other field type.
143
- if ( ! $wpmem->user->post_data[ $meta_key ] ) {
144
  $wpmem_themsg = sprintf( $wpmem->get_text( 'reg_empty_field' ), __( $field['label'], 'wp-members' ) );
145
  }
146
  }
140
  }
141
  } else {
142
  // If the required field is any other field type.
143
+ if ( null == $wpmem->user->post_data[ $meta_key ] ) {
144
  $wpmem_themsg = sprintf( $wpmem->get_text( 'reg_empty_field' ), __( $field['label'], 'wp-members' ) );
145
  }
146
  }
readme.txt CHANGED
@@ -2,8 +2,8 @@
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.0
6
- Stable tag: 3.2.5.1
7
  License: GPLv2
8
 
9
  == Description ==
@@ -101,7 +101,7 @@ The FAQs are maintained at https://rocketgeek.com/plugins/wp-members/docs/faqs/
101
  == Upgrade Notice ==
102
 
103
  WP-Members 3.2.0 is a major update. See changelog for important details. Minimum WP version is 4.0.
104
- WP-Members 3.2.5 is primarily a feature update, with some fixes. See changelog for details.
105
 
106
  == Screenshots ==
107
 
@@ -124,10 +124,26 @@ WP-Members 3.2.5 is primarily a feature update, with some fixes. See changelog f
124
 
125
  == Changelog ==
126
 
127
- = 3.2.5.1 =
128
-
129
- * Fixes bug in 3.2.5 with the [wpmem_field] shortcode not displaying correctly.
130
- * Reintroduces WPMEM_DEBUG constant (which is used in outside extensions).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  = 3.2.5 =
133
 
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.2
6
+ Stable tag: 3.2.6
7
  License: GPLv2
8
 
9
  == Description ==
101
  == Upgrade Notice ==
102
 
103
  WP-Members 3.2.0 is a major update. See changelog for important details. Minimum WP version is 4.0.
104
+ WP-Members 3.2.6 is a security release with some additional updates. See changelog for details.
105
 
106
  == Screenshots ==
107
 
124
 
125
  == Changelog ==
126
 
127
+ = 3.2.6 =
128
+
129
+ * Added nonce to short form (long form was added in 3.2.5).
130
+ * Password change function only can be fired if user is logged in.
131
+ * Added "all" argument to wpmem_user_data() to retrieve either all user meta or WP-Members fields only.
132
+ * Added $date argument to wpmem_set_user_product(). Allows specific date to be set using API.
133
+ * Added wpmem_admin_after_profile_table and wpmem_user_after_profile_table actions.
134
+ * get_user_products() returns empty array if no products (previously boolean).
135
+ * Rebuild of [wpmem_field] logic for field type. Combined multiple conditions into a single switch.
136
+ * Update password reset form - password field should be "text" class.
137
+ * Added membership field type for allowing selection of a membership at registration.
138
+ * Login form updated from "Username" to "Username or Email".
139
+ * Added $arr parameter to wpmem_login_form_rows filter.
140
+ * Added file's post ID to post_data array.
141
+ * Update to evaluate required fields as not null (instead of false).
142
+ * Added wpmem_tos_link_tag filter.
143
+ * Added $button_html parameter to wpmem_register_form_buttons filter.
144
+ * Added wpmem_serve_menu filter.
145
+ * Fixed display issue with password shortcode which caused message dialog to display in default state.
146
+ * Fixed console error with short form nonce.
147
 
148
  = 3.2.5 =
149
 
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/users-guide/">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.2.5.1
7
  Author: Chad Butler
8
  Author URI: http://butlerblog.com/
9
  Text Domain: wp-members
@@ -66,7 +66,7 @@ if ( ! defined( 'ABSPATH' ) ) {
66
  }
67
 
68
  // Initialize constants.
69
- define( 'WPMEM_VERSION', '3.2.5.1' );
70
  define( 'WPMEM_DB_VERSION', '2.1.4' );
71
  define( 'WPMEM_DIR', plugin_dir_url ( __FILE__ ) );
72
  define( 'WPMEM_PATH', plugin_dir_path( __FILE__ ) );
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/users-guide/">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.2.6
7
  Author: Chad Butler
8
  Author URI: http://butlerblog.com/
9
  Text Domain: wp-members
66
  }
67
 
68
  // Initialize constants.
69
+ define( 'WPMEM_VERSION', '3.2.6' );
70
  define( 'WPMEM_DB_VERSION', '2.1.4' );
71
  define( 'WPMEM_DIR', plugin_dir_url ( __FILE__ ) );
72
  define( 'WPMEM_PATH', plugin_dir_path( __FILE__ ) );