s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) - Version 140520

Version Description

= v140520 =

(Maintenance Release) Upgrade immediately!

Download this release

Release Info

Developer JasWSInc
Plugin Icon 128x128 s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members)
Version 140520
Comparing to
See all releases

Code changes from version 140423 to 140520

checksum.txt CHANGED
@@ -1 +1 @@
1
- 2901368de4b8eaf96fc4f5d0dcd5451c
1
+ 8ff3c403b6da2ebb6c3e93dafb2f9314
includes/classes/access-cap-times.inc.php ADDED
@@ -0,0 +1,240 @@
1
+ <?php
2
+ /**
3
+ * Access CAP Times.
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\CCAPS
15
+ * @since 140514
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_access_cap_times'))
21
+ {
22
+ /**
23
+ * Access CAP Times.
24
+ *
25
+ * @package s2Member\CCAPS
26
+ * @since 140514
27
+ */
28
+ class c_ws_plugin__s2member_access_cap_times
29
+ {
30
+
31
+ /**
32
+ * @var array Previous array of user CAPS.
33
+ * For internal use only.
34
+ */
35
+ protected static $prev_caps_by_user = array();
36
+
37
+ /**
38
+ * Get user caps before udpate.
39
+ *
40
+ * @package s2Member\CCAPS
41
+ * @since 140514
42
+ *
43
+ * @attaches-to ``add_action('add_user_meta')`` (indirectly)
44
+ * @attaches-to ``add_action('update_user_meta')``
45
+ *
46
+ * @param integer $meta_id Meta row ID in database.
47
+ * @param integer $object_id User ID.
48
+ * @param string $meta_key Meta key.
49
+ * @param mixed $meta_value Meta value.
50
+ */
51
+ public static function get_user_caps_before_update($meta_id, $object_id, $meta_key, $meta_value)
52
+ {
53
+ $wpdb = $GLOBALS['wpdb'];
54
+ /** @var $wpdb \wpdb For IDEs. */
55
+
56
+ if(strpos($meta_key, 'capabilities') === FALSE || $meta_key !== $wpdb->get_blog_prefix().'capabilities')
57
+ return; // Not updating caps.
58
+
59
+ $user_id = (integer)$object_id;
60
+ $user = new WP_User($user_id);
61
+ if(!$user->ID || !$user->exists())
62
+ return; // Not a valid user.
63
+
64
+ self::$prev_caps_by_user[$user_id] = $user->caps;
65
+ }
66
+
67
+ /**
68
+ * Get user caps before udpate.
69
+ *
70
+ * @package s2Member\CCAPS
71
+ * @since 140514
72
+ *
73
+ * @attaches-to ``add_action('add_user_meta')``
74
+ *
75
+ * @param integer $object_id User ID.
76
+ * @param string $meta_key Meta key.
77
+ * @param mixed $meta_value Meta value.
78
+ */
79
+ public static function get_user_caps_before_update_on_add($object_id, $meta_key, $meta_value)
80
+ {
81
+ self::get_user_caps_before_update(0, $object_id, $meta_key, $meta_value);
82
+ }
83
+
84
+ /**
85
+ * Logs access capability times.
86
+ *
87
+ * @package s2Member\CCAPS
88
+ * @since 140514
89
+ *
90
+ * @attaches-to ``add_action('added_user_meta')``
91
+ * @attaches-to ``add_action('updated_user_meta')``
92
+ * @attaches-to ``add_action('deleted_user_meta')`` (indirectly)
93
+ *
94
+ * @param integer $meta_id Meta row ID in database.
95
+ * @param integer $object_id User ID.
96
+ * @param string $meta_key Meta key.
97
+ * @param mixed $meta_value Meta value.
98
+ */
99
+ public static function log_access_cap_times($meta_id, $object_id, $meta_key, $meta_value)
100
+ {
101
+ $wpdb = $GLOBALS['wpdb'];
102
+ /** @var $wpdb \wpdb For IDEs. */
103
+
104
+ if(strpos($meta_key, 'capabilities') === FALSE || $meta_key !== $wpdb->get_blog_prefix().'capabilities')
105
+ return; // Not updating caps.
106
+
107
+ $user_id = (integer)$object_id;
108
+ $user = new WP_User($user_id);
109
+ if(!$user->ID || !$user->exists())
110
+ return; // Not a valid user.
111
+
112
+ $caps['prev'] = !empty(self::$prev_caps_by_user[$user_id]) ? self::$prev_caps_by_user[$user_id] : array();
113
+ self::$prev_caps_by_user = array(); // Reset this in case `get_user_caps_before_update()` doesn't run somehow.
114
+ $caps['now'] = is_array($meta_value) ? $meta_value : array();
115
+ $role_objects = $GLOBALS['wp_roles']->role_objects;
116
+
117
+ foreach($caps as &$_caps_prev_now)
118
+ {
119
+ foreach(array_intersect(array_keys($_caps_prev_now), array_keys($role_objects)) as $_role)
120
+ if($_caps_prev_now[$_role]) // If the cap (i.e. the role) is enabled; merge its caps.
121
+ $_caps_prev_now = array_merge($_caps_prev_now, $role_objects[$_role]->capabilities);
122
+
123
+ $_s2_caps_prev_now = array();
124
+ foreach($_caps_prev_now as $_cap => $_enabled)
125
+ if(strpos($_cap, 'access_s2member_') === 0)
126
+ $_s2_caps_prev_now[substr($_cap, 16)] = $_enabled;
127
+ $_caps_prev_now = $_s2_caps_prev_now;
128
+ }
129
+ unset($_s2_caps_prev_now, $_caps_prev_now, $_role, $_cap, $_enabled);
130
+
131
+ $ac_times = get_user_option('s2member_access_cap_times', $user_id);
132
+ if(!is_array($ac_times)) $ac_times = array();
133
+ $time = (float)time();
134
+
135
+ foreach($caps['prev'] as $_cap => $_was_enabled)
136
+ if($_was_enabled && empty($caps['now'][$_cap]))
137
+ $ac_times[number_format(($time += .0001), 4, '.', '')] = '-'.$_cap;
138
+ unset($_cap, $_was_enabled);
139
+
140
+ foreach($caps['now'] as $_cap => $_now_enabled)
141
+ if($_now_enabled && empty($caps['prev'][$_cap]))
142
+ $ac_times[number_format(($time += .0001), 4, '.', '')] = $_cap;
143
+ unset($_cap, $_now_enabled);
144
+
145
+ update_user_option($user_id, 's2member_access_cap_times', $ac_times);
146
+ }
147
+
148
+ /**
149
+ * Logs access capability times.
150
+ *
151
+ * @package s2Member\CCAPS
152
+ * @since 140514
153
+ *
154
+ * @attaches-to ``add_action('deleted_user_meta')``
155
+ *
156
+ * @param array $meta_ids Meta row ID in database.
157
+ * @param integer $object_id User ID.
158
+ * @param string $meta_key Meta key.
159
+ */
160
+ public static function log_access_cap_times_on_delete($meta_ids, $object_id, $meta_key)
161
+ {
162
+ $wpdb = $GLOBALS['wpdb'];
163
+ /** @var $wpdb \wpdb For IDEs. */
164
+
165
+ if(strpos($meta_key, 'capabilities') === FALSE || $meta_key !== $wpdb->get_blog_prefix().'capabilities')
166
+ return; // Not updating caps.
167
+
168
+ if(!is_array($meta_ids) || !$meta_ids)
169
+ return; // Nothing to do.
170
+
171
+ if(count($meta_ids) > 50)
172
+ if(function_exists('set_time_limit'))
173
+ @set_time_limit(900);
174
+
175
+ $user_ids = $wpdb->get_col("SELECT DISTINCT `user_id` FROM `".$wpdb->usermeta."` WHERE `umeta_id` IN('".implode("','", $meta_ids)."')");
176
+
177
+ if(count($user_ids) > 50)
178
+ if(function_exists('set_time_limit'))
179
+ @set_time_limit(900);
180
+
181
+ foreach($user_ids as $_user_id)
182
+ self::log_access_cap_times(0, $_user_id, $meta_key, array());
183
+ unset($_user_id);
184
+ }
185
+
186
+ /**
187
+ * Gets access capability times.
188
+ *
189
+ * @package s2Member\CCAPS
190
+ * @since 140514
191
+ *
192
+ * @param integer $user_id WP User ID.
193
+ * @param array $access_caps Optional. If not passed, this returns all times for all caps.
194
+ * If passed, please pass an array of specific access capabilities to get the times for.
195
+ * If removal times are desired, you should add a `-` prefix.
196
+ * e.g. `array('ccap_music','level2','-ccap_video')`
197
+ *
198
+ * @return array An array of all access capability times.
199
+ * Keys are UTC timestamps (w/ microtime precision), values are the capabilities (including `-` prefixed removals).
200
+ * e.g. `array('1234567890.0001' => 'ccap_music', '1234567890.0002' => 'level2', '1234567890.0003' => '-ccap_video')`
201
+ */
202
+ public static function get_access_cap_times($user_id, $access_caps = array())
203
+ {
204
+ $ac_times = array();
205
+ if(($user_id = (integer)$user_id))
206
+ {
207
+ $ac_times = get_user_option('s2member_access_cap_times', $user_id);
208
+ if(!is_array($ac_times)) $ac_times = array();
209
+
210
+ /* ------- Begin back compat. with `s2member_paid_registration_times`. */
211
+
212
+ // $update_ac_times = empty($ac_times) ? FALSE : TRUE;
213
+ $ac_times_min = !empty($ac_times) ? min(array_keys($ac_times)) : 0;
214
+ if(($r_time = c_ws_plugin__s2member_registration_times::registration_time()) && (empty($ac_times_min) || $r_time < $ac_times_min))
215
+ $ac_times[number_format(($r_time += .0001), 4, '.', '')] = 'level0';
216
+
217
+ if(is_array($pr_times = get_user_option('s2member_paid_registration_times', $user_id)))
218
+ {
219
+ $role_objects = $GLOBALS['wp_roles']->role_objects;
220
+ foreach($pr_times as $_level => $_time)
221
+ if(isset($role_objects['s2member_'.$_level]) && (empty($ac_times_min) || $_time < $ac_times_min))
222
+ foreach(array_keys($role_objects['s2member_'.$_level]->capabilities) as $_cap)
223
+ if(strpos($_cap, 'access_s2member_') === 0)
224
+ $ac_times[number_format(($_time += .0001), 4, '.', '')] = substr($_cap, 16);
225
+ unset($_level, $_time, $_cap);
226
+ }
227
+ /* ------- End back compat. with `s2member_paid_registration_times`. */
228
+
229
+ if($access_caps)
230
+ $ac_times = array_intersect($ac_times, (array)$access_caps);
231
+
232
+ ksort($ac_times, SORT_NUMERIC);
233
+
234
+ //if($update_ac_times)
235
+ // update_user_option($user_id, 's2member_access_cap_times', $ac_times);
236
+ }
237
+ return apply_filters('ws_plugin__s2member_get_access_cap_times', $ac_times, get_defined_vars());
238
+ }
239
+ }
240
+ }
includes/classes/custom-reg-fields.inc.php CHANGED
@@ -274,12 +274,13 @@ if(!class_exists("c_ws_plugin__s2member_custom_reg_fields"))
274
* @package s2Member\Custom_Reg_Fields
275
* @since 3.5
276
*
277
- * @param str|int $_level Optional. Defaults to the current User's Access Level number.
278
* You can either pass in a numeric Level number, or the string `auto-detection`.
279
- * @param str $_editable_context Optional. One of `profile|profile-view|registration`.
280
* @return array Array of Custom Field IDs applicable.
281
*/
282
- public static function custom_fields_configured_at_level($_level = "auto-detection", $_editable_context = FALSE)
283
{
284
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
285
do_action("ws_plugin__s2member_before_custom_fields_configured_at_level", get_defined_vars());
@@ -296,7 +297,7 @@ if(!class_exists("c_ws_plugin__s2member_custom_reg_fields"))
296
foreach(json_decode($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
297
if($level === "any" || $field["levels"] === "all" || in_array($level, preg_split("/[;,]+/", preg_replace("/[^0-9;,]/", "", $field["levels"]))))
298
if(empty($_editable_context) || $_editable_context === "administrative" || ($_editable_context === "registration" && $field["editable"] !== "no-always-invisible" && $field["editable"] !== "yes-invisible") || (($_editable_context === "profile" || $_editable_context === "profile-view") && $field["editable"] !== "no-invisible" && $field["editable"] !== "no-always-invisible"))
299
- $configured[] = /* Add this to the array. */ $field["id"];
300
}
301
return apply_filters("ws_plugin__s2member_custom_fields_configured_at_level", ((!empty($configured)) ? $configured : array()), get_defined_vars());
302
}
@@ -558,6 +559,244 @@ if(!class_exists("c_ws_plugin__s2member_custom_reg_fields"))
558
559
return /* Return for uniformity. */;
560
}
561
}
562
- }
563
- ?>
274
* @package s2Member\Custom_Reg_Fields
275
* @since 3.5
276
*
277
+ * @param string|int $_level Optional. Defaults to the current User's Access Level number.
278
* You can either pass in a numeric Level number, or the string `auto-detection`.
279
+ * @param string $_editable_context Optional. One of `profile|profile-view|registration`.
280
+ * @param boolean $full_config Optional. Defaults to a `FALSE` value. `TRUE` to get a full array for each field configuration.
281
* @return array Array of Custom Field IDs applicable.
282
*/
283
+ public static function custom_fields_configured_at_level($_level = "auto-detection", $_editable_context = FALSE, $full_config = FALSE)
284
{
285
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
286
do_action("ws_plugin__s2member_before_custom_fields_configured_at_level", get_defined_vars());
297
foreach(json_decode($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
298
if($level === "any" || $field["levels"] === "all" || in_array($level, preg_split("/[;,]+/", preg_replace("/[^0-9;,]/", "", $field["levels"]))))
299
if(empty($_editable_context) || $_editable_context === "administrative" || ($_editable_context === "registration" && $field["editable"] !== "no-always-invisible" && $field["editable"] !== "yes-invisible") || (($_editable_context === "profile" || $_editable_context === "profile-view") && $field["editable"] !== "no-invisible" && $field["editable"] !== "no-always-invisible"))
300
+ $configured[] = /* Add this to the array. */ $full_config ? $field : $field["id"];
301
}
302
return apply_filters("ws_plugin__s2member_custom_fields_configured_at_level", ((!empty($configured)) ? $configured : array()), get_defined_vars());
303
}
559
560
return /* Return for uniformity. */;
561
}
562
+
563
+ /**
564
+ * Validates custom registration/profile fields.
565
+ *
566
+ * @param array $input Array of data input by a user.
567
+ * Array keys should match custom registration field variable names.
568
+ *
569
+ * @param array $fields_to_validate An array of custom registration/profile field configurations.
570
+ * Only include the configurations for those fields that need to be validated against the `$input`.
571
+ *
572
+ * @return array An array of errors; else an empty array.
573
+ * If there are errors, the array keys are the custom registration field variable names.
574
+ * Each array value is an error message with basic HTML markup.
575
+ */
576
+ public static function validation_errors($input, $fields_to_validate)
577
+ {
578
+ $input = (array)$input;
579
+ $fields_to_validate = (array)$fields_to_validate;
580
+
581
+ $errors = array(); // Initialize the array of errors.
582
+ $force_personal_emails = isset($GLOBALS['WS_PLUGIN__']['s2member']['o']['custom_reg_force_personal_emails'][0]) ? TRUE : FALSE;
583
+ $non_personal_email_users = '/^(?:'.implode('|', preg_split('/[\s;,]+/', preg_quote($GLOBALS['WS_PLUGIN__']['s2member']['o']['custom_reg_force_personal_emails'], '/'))).'@/i';
584
+
585
+ foreach($fields_to_validate as $_field)
586
+ {
587
+ if(empty($_field['id'])) continue; // Not applicable.
588
+ $_field_type = !empty($_field['type']) ? $_field['type'] : '';
589
+ $_field_var = preg_replace('/[^a-z0-9]/i', '_', strtolower($_field['id']));
590
+ $_field_id_class = preg_replace('/_/', '-', $_field_var);
591
+
592
+ $_field_required = !empty($_field['required']) && $_field['required'] === 'yes';
593
+ $_field_expects = !empty($_field['expected']) ? $_field['expected'] : '';
594
+ $_field_label = !empty($_field['label']) ? $_field['label'] : ucwords(str_replace('_', ' ', $_field_var));
595
+
596
+ switch($_field_type)
597
+ {
598
+ case 'text':
599
+ case 'textarea':
600
+ case 'checkbox':
601
+ case 'pre_checkbox':
602
+ case 'radios':
603
+ case 'select':
604
+ if(isset($input[$_field_var]) && !is_string($input[$_field_var]))
605
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Invalid data type. Expecting a string.', 's2member-front', 's2member').'</em>';
606
+ break;
607
+
608
+ case 'checkboxes':
609
+ case 'selects':
610
+ if(isset($input[$_field_var]) && !is_array($input[$_field_var]))
611
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Invalid data type. Expecting an array.', 's2member-front', 's2member').'</em>';
612
+ break;
613
+
614
+ default: // Default case handler for best security.
615
+ if(isset($input[$_field_var]) && !is_string($input[$_field_var]))
616
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Invalid data type. Expecting a string.', 's2member-front', 's2member').'</em>';
617
+ break;
618
+ }
619
+ if(empty($errors[$_field_var]) && $_field_required) switch($_field_type)
620
+ {
621
+ case 'text':
622
+ case 'textarea':
623
+ if(!isset($input[$_field_var]) || !is_string($input[$_field_var]) || !isset($input[$_field_var][0]))
624
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('This is a required field, please try again.', 's2member-front', 's2member').'</em>';
625
+ break;
626
+
627
+ case 'checkbox':
628
+ case 'pre_checkbox':
629
+ if(!isset($input[$_field_var]) || !is_string($input[$_field_var]) || !isset($input[$_field_var][0]))
630
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Required. This box must be checked.', 's2member-front', 's2member').'</em>';
631
+ break;
632
+
633
+ case 'checkboxes':
634
+ if(!isset($input[$_field_var]) || !is_array($input[$_field_var]) || empty($input[$_field_var]))
635
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please check at least one of the boxes.', 's2member-front', 's2member').'</em>';
636
+ break;
637
+
638
+ case 'radios':
639
+ if(!isset($input[$_field_var]) || !is_string($input[$_field_var]))
640
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please select one of the options.', 's2member-front', 's2member').'</em>';
641
+ break;
642
+
643
+ case 'select':
644
+ if(!isset($input[$_field_var]) || !is_string($input[$_field_var]) || !isset($input[$_field_var][0]))
645
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please select one of the options.', 's2member-front', 's2member').'</em>';
646
+ break;
647
+
648
+ case 'selects':
649
+ if(!isset($input[$_field_var]) || !is_array($input[$_field_var]) || empty($input[$_field_var]))
650
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please select at least one of the options.', 's2member-front', 's2member').'</em>';
651
+ break;
652
+
653
+ default: // Default case handler for best security.
654
+ if(!isset($input[$_field_var]) || !is_string($input[$_field_var]) || !isset($input[$_field_var][0]))
655
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('This is a required field, please try again.', 's2member-front', 's2member').'</em>';
656
+ break;
657
+ }
658
+ if(empty($errors[$_field_var]) && $_field_expects) switch($_field_type)
659
+ {
660
+ case 'text':
661
+ case 'textarea':
662
+ if(isset($input[$_field_var]) && is_string($input[$_field_var]) && isset($input[$_field_var][0])) switch($_field_expects)
663
+ {
664
+ case 'numeric-wp-commas':
665
+ if(!preg_match('/^[0-9][0-9\.,]*#x2F;', $input[$_field_var]))
666
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be numeric (with or without decimals, commas allowed).', 's2member-front', 's2member').'</em>';
667
+ break;
668
+
669
+ case 'numeric':
670
+ if(!preg_match('/^[0-9][0-9\.]*#x2F;', $input[$_field_var]))
671
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be numeric (with or without decimals, no commas).', 's2member-front', 's2member').'</em>';
672
+ break;
673
+
674
+ case 'integer':
675
+ if(!preg_match('/^[0-9]+#x2F;', $input[$_field_var]))
676
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be an integer (a whole number, without any decimals).', 's2member-front', 's2member').'</em>';
677
+ break;
678
+
679
+ case 'integer-gt-0':
680
+ if(!preg_match('/^[0-9]+#x2F;', $input[$_field_var]) || $input[$_field_var] <= 0)
681
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be an integer &gt; 0 (whole number, no decimals, greater than 0).', 's2member-front', 's2member').'</em>';
682
+ break;
683
+
684
+ case 'float':
685
+ if(!preg_match('/^[0-9\.]+#x2F;', $input[$_field_var]) || !preg_match('/[0-9]/', $input[$_field_var]) || !preg_match('/\./', $input[$_field_var]))
686
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a float (floating point number, decimals required).', 's2member-front', 's2member').'</em>';
687
+ break;
688
+
689
+ case 'float-gt-0':
690
+ if(!preg_match('/^[0-9\.]+#x2F;', $input[$_field_var]) || !preg_match('/[0-9]/', $input[$_field_var]) || !preg_match('/\./', $input[$_field_var]) || $input[$_field_var] <= 0)
691
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a float &gt; 0 (floating point number, decimals required, greater than 0).', 's2member-front', 's2member').'</em>';
692
+ break;
693
+
694
+ case 'date':
695
+ if(!preg_match('/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}#x2F;', $input[$_field_var]))
696
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a date (required date format: dd/mm/yyyy).', 's2member-front', 's2member').'</em>';
697
+ break;
698
+
699
+ case 'email':
700
+ if(!is_email($input[$_field_var]))
701
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a valid email address.', 's2member-front', 's2member').'</em>';
702
+
703
+ else if($force_personal_emails && $non_personal_email_users && preg_match($non_personal_email_users, $input[$_field_var]))
704
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'.sprintf(_x('Please use a personal email address. Addresses like &lt;%s@&gt; are problematic.', 's2member-front', 's2member'), substr($input[$_field_var], 0, strpos($input[$_field_var], '@'))).'</em>';
705
+ break;
706
+
707
+ case 'url':
708
+ if(!preg_match('/^https?\:\/\/.+#x2F;i', $input[$_field_var]))
709
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a full URL (starting with http or https).', 's2member-front', 's2member').'</em>';
710
+ break;
711
+
712
+ case 'domain':
713
+ if(!preg_match('/^[a-zA-Z0-9]+(?:\-*[a-zA-Z0-9]+)*(?:\.[a-zA-Z0-9]+(?:\-*[a-zA-Z0-9]+)*)*(?:\.[a-zA-Z][a-zA-Z0-9]+)?#x2F;', $input[$_field_var]))
714
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a domain name (domain name only, without http).', 's2member-front', 's2member').'</em>';
715
+ break;
716
+
717
+ case 'phone':
718
+ if(!preg_match('/^[0-9 ()\-]+#x2F;', $input[$_field_var]) || strlen(preg_replace('/[^0-9]+/', '', $input[$_field_var])) !== 10)
719
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a phone # (10 digits w/possible hyphens, spaces, brackets).', 's2member-front', 's2member').'</em>';
720
+ break;
721
+
722
+ case 'uszip':
723
+ if(!preg_match('/^[0-9]{5}(?:\-[0-9]{4})?#x2F;', $input[$_field_var]))
724
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a US zipcode (5-9 digits w/ possible hyphen).', 's2member-front', 's2member').'</em>';
725
+ break;
726
+
727
+ case 'cazip':
728
+ if(!preg_match('/^[0-9A-Z]{3} ?[0-9A-Z]{3}#x2F;i', $input[$_field_var]))
729
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a Canadian zipcode (6 alpha-numerics w/ possible space).', 's2member-front', 's2member').'</em>';
730
+ break;
731
+
732
+ case 'uczip':
733
+ if(!preg_match('/^[0-9]{5}(?:\-[0-9]{4})?#x2F;', $input[$_field_var]) && !preg_match('/^[0-9A-Z]{3} ?[0-9A-Z]{3}#x2F;i', $input[$_field_var]))
734
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Must be a zipcode (either a US or Canadian zipcode).', 's2member-front', 's2member').'</em>';
735
+ break;
736
+
737
+ default: // Handle others dynamically here.
738
+
739
+ if(preg_match('/^alphanumerics\-spaces\-punctuation\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[a-z 0-9\/\\\\,.?:;"\'{}[\]\^|+=_()*&%$#@!`~\-]+#x2F;i', $input[$_field_var]))
740
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use alphanumerics, spaces &amp; punctuation only.', 's2member-front', 's2member').'</em>';
741
+
742
+ else if(preg_match('/^alphanumerics\-spaces\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[a-z 0-9]+#x2F;i', $input[$_field_var]))
743
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use alphanumerics &amp; spaces only.', 's2member-front', 's2member').'</em>';
744
+
745
+ else if(preg_match('/^alphanumerics\-punctuation\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[a-z0-9\/\\\\,.?:;"\'{}[\]\^|+=_()*&%$#@!`~\-]+#x2F;i', $input[$_field_var]))
746
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use alphanumerics &amp; punctuation only (no spaces).', 's2member-front', 's2member').'</em>';
747
+
748
+ else if(preg_match('/^alphanumerics\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[a-z0-9]+#x2F;i', $input[$_field_var]))
749
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use alphanumerics only (no spaces/punctuation).', 's2member-front', 's2member').'</em>';
750
+
751
+ else if(preg_match('/^alphabetics\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[a-z]+#x2F;i', $input[$_field_var]))
752
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use alphabetics only (no digits/spaces/punctuation).', 's2member-front', 's2member').'</em>';
753
+
754
+ else if(preg_match('/^numerics\-[0-9]+(?:\-e)?#x2F;', $_field_expects) && !preg_match('/^[0-9]+#x2F;i', $input[$_field_var]))
755
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'._x('Please use numeric digits only.', 's2member-front', 's2member').'</em>';
756
+
757
+ else if(preg_match('/^(?:any|alphanumerics\-spaces\-punctuation|alphanumerics\-spaces|alphanumerics\-punctuation|alphanumerics|alphabetics|numerics)\-[0-9]+(?:\-e)?#x2F;', $_field_expects))
758
+ {
759
+ $_field_expects_split = explode('-', $_field_expects);
760
+ $_field_expects_length = (integer)$_field_expects_split[1];
761
+ $_field_expects_exact_length = !empty($_field_expects_split[2]) && $_field_expects_split[2] === 'e';
762
+
763
+ if($_field_expects_exact_length && strlen($input[$_field_var]) !== $_field_expects_length)
764
+ {
765
+ if($_field_expects_split[0] === 'numerics')
766
+ {
767
+ if($_field_expects_length === 1)
768
+ $_field_expects_digits_chars = _x('digit', 's2member-front', 's2member');
769
+ else $_field_expects_digits_chars = _x('digits', 's2member-front', 's2member');
770
+ }
771
+ else if($_field_expects_length === 1)
772
+ $_field_expects_digits_chars = _x('character', 's2member-front', 's2member');
773
+ else $_field_expects_digits_chars = _x('characters', 's2member-front', 's2member');
774
+
775
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'.sprintf(_x('Must be exactly %s %s.', 's2member-front', 's2member'), $_field_expects_length, $_field_expects_digits_chars).'</em>';
776
+ }
777
+ else if(strlen($input[$_field_var]) < $_field_expects_length)
778
+ {
779
+ if($_field_expects_split[0] === 'numerics')
780
+ {
781
+ if($_field_expects_length === 1)
782
+ $_field_expects_digits_chars = _x('digit', 's2member-front', 's2member');
783
+ else $_field_expects_digits_chars = _x('digits', 's2member-front', 's2member');
784
+ }
785
+ else if($_field_expects_length === 1)
786
+ $_field_expects_digits_chars = _x('character', 's2member-front', 's2member');
787
+ else $_field_expects_digits_chars = _x('characters', 's2member-front', 's2member');
788
+
789
+ $errors[$_field_var] = '<strong>'.$_field_label.'</strong><br />&nbsp;&nbsp;<em>'.sprintf(_x('Must be at least %s %s.', 's2member-front', 's2member'), $_field_expects_length, $_field_expects_digits_chars).'</em>';
790
+ }
791
+ }
792
+ break;
793
+ }
794
+ break;
795
+ }
796
+ }
797
+ unset($_field, $_field_type, $_field_var, $_field_id_class, $_field_required, $_field_label, $_field_expects, $_field_expects_split, $_field_expects_length, $_field_expects_exact_length, $_field_expects_digits_chars);
798
+
799
+ return apply_filters('c_ws_plugin__s2member_custom_reg_field_validation_errors', $errors, get_defined_vars());
800
+ }
801
}
802
+ }
includes/classes/profile-mods-4bp-in.inc.php CHANGED
@@ -56,6 +56,7 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_4bp_in"))
56
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
57
if ($fields_applicable = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level ("auto-detection", "profile"))
58
{
59
$_existing_fields = get_user_option ("s2member_custom_fields", $user_id);
60
61
foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
@@ -70,7 +71,13 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_4bp_in"))
70
else // Else ``unset()``.
71
unset($fields[$field_var]);
72
}
73
- else if ($field["required"] === "yes" && (!isset ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) || (!is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])) || (is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && empty ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])) || (is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !strlen ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))))
74
{
75
if (isset ($_existing_fields[$field_var]) && ((is_array ($_existing_fields[$field_var]) && !empty ($_existing_fields[$field_var])) || (is_string ($_existing_fields[$field_var]) && strlen ($_existing_fields[$field_var]))))
76
$fields[$field_var] = $_existing_fields[$field_var];
@@ -79,7 +86,9 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_4bp_in"))
79
}
80
else if (isset ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))
81
{
82
- if ((is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !empty ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])) || (is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && strlen ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])))
83
$fields[$field_var] = $_p["ws_plugin__s2member_profile_4bp_" . $field_var];
84
else // Else ``unset()``.
85
unset($fields[$field_var]);
56
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
57
if ($fields_applicable = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level ("auto-detection", "profile"))
58
{
59
+ $fields = array(); // Initialize the array of fields.
60
$_existing_fields = get_user_option ("s2member_custom_fields", $user_id);
61
62
foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
71
else // Else ``unset()``.
72
unset($fields[$field_var]);
73
}
74
+ else if ( // If the field is required but missing; or it was provided but invalid...
75
+ ($field["required"] === "yes" && (!isset ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])
76
+ || (!is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))
77
+ || (is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && empty ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))
78
+ || (is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !strlen ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))))
79
+ || (isset ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && c_ws_plugin__s2member_custom_reg_fields::validation_errors(array($field_var => $_p["ws_plugin__s2member_profile_4bp_" . $field_var]), array($field)))
80
+ )
81
{
82
if (isset ($_existing_fields[$field_var]) && ((is_array ($_existing_fields[$field_var]) && !empty ($_existing_fields[$field_var])) || (is_string ($_existing_fields[$field_var]) && strlen ($_existing_fields[$field_var]))))
83
$fields[$field_var] = $_existing_fields[$field_var];
86
}
87
else if (isset ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))
88
{
89
+ if (((is_array ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && !empty ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]))
90
+ || (is_string ($_p["ws_plugin__s2member_profile_4bp_" . $field_var]) && strlen ($_p["ws_plugin__s2member_profile_4bp_" . $field_var])))
91
+ && !c_ws_plugin__s2member_custom_reg_fields::validation_errors(array($field_var => $_p["ws_plugin__s2member_profile_4bp_" . $field_var]), array($field)))
92
$fields[$field_var] = $_p["ws_plugin__s2member_profile_4bp_" . $field_var];
93
else // Else ``unset()``.
94
unset($fields[$field_var]);
includes/classes/profile-mods-in.inc.php CHANGED
@@ -78,6 +78,7 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_in"))
78
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
79
if ($fields_applicable = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level ("auto-detection", "profile"))
80
{
81
$_existing_fields = get_user_option ("s2member_custom_fields", $user_id);
82
83
foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
@@ -92,7 +93,13 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_in"))
92
else // Else ``unset()``.
93
unset($fields[$field_var]);
94
}
95
- else if ($field["required"] === "yes" && (!isset ($_p["ws_plugin__s2member_profile_" . $field_var]) || (!is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && !is_string ($_p["ws_plugin__s2member_profile_" . $field_var])) || (is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && empty ($_p["ws_plugin__s2member_profile_" . $field_var])) || (is_string ($_p["ws_plugin__s2member_profile_" . $field_var]) && !strlen ($_p["ws_plugin__s2member_profile_" . $field_var]))))
96
{
97
if (isset ($_existing_fields[$field_var]) && ((is_array ($_existing_fields[$field_var]) && !empty ($_existing_fields[$field_var])) || (is_string ($_existing_fields[$field_var]) && strlen ($_existing_fields[$field_var]))))
98
$fields[$field_var] = $_existing_fields[$field_var];
@@ -101,7 +108,9 @@ if (!class_exists ("c_ws_plugin__s2member_profile_mods_in"))
101
}
102
else if (isset ($_p["ws_plugin__s2member_profile_" . $field_var]))
103
{
104
- if ((is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && !empty ($_p["ws_plugin__s2member_profile_" . $field_var])) || (is_string ($_p["ws_plugin__s2member_profile_" . $field_var]) && strlen ($_p["ws_plugin__s2member_profile_" . $field_var])))
105
$fields[$field_var] = $_p["ws_plugin__s2member_profile_" . $field_var];
106
else // Else ``unset()``.
107
unset($fields[$field_var]);
78
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
79
if ($fields_applicable = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level ("auto-detection", "profile"))
80
{
81
+ $fields = array(); // Initialize the array of fields.
82
$_existing_fields = get_user_option ("s2member_custom_fields", $user_id);
83
84
foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
93
else // Else ``unset()``.
94
unset($fields[$field_var]);
95
}
96
+ else if ( // If the field is required but missing; or it was provided but invalid...
97
+ ($field["required"] === "yes" && (!isset ($_p["ws_plugin__s2member_profile_" . $field_var])
98
+ || (!is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && !is_string ($_p["ws_plugin__s2member_profile_" . $field_var]))
99
+ || (is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && empty ($_p["ws_plugin__s2member_profile_" . $field_var]))
100
+ || (is_string ($_p["ws_plugin__s2member_profile_" . $field_var]) && !strlen ($_p["ws_plugin__s2member_profile_" . $field_var]))))
101
+ || (isset ($_p["ws_plugin__s2member_profile_" . $field_var]) && c_ws_plugin__s2member_custom_reg_fields::validation_errors(array($field_var => $_p["ws_plugin__s2member_profile_" . $field_var]), array($field)))
102
+ )
103
{
104
if (isset ($_existing_fields[$field_var]) && ((is_array ($_existing_fields[$field_var]) && !empty ($_existing_fields[$field_var])) || (is_string ($_existing_fields[$field_var]) && strlen ($_existing_fields[$field_var]))))
105
$fields[$field_var] = $_existing_fields[$field_var];
108
}
109
else if (isset ($_p["ws_plugin__s2member_profile_" . $field_var]))
110
{
111
+ if (((is_array ($_p["ws_plugin__s2member_profile_" . $field_var]) && !empty ($_p["ws_plugin__s2member_profile_" . $field_var]))
112
+ || (is_string ($_p["ws_plugin__s2member_profile_" . $field_var]) && strlen ($_p["ws_plugin__s2member_profile_" . $field_var])))
113
+ && !c_ws_plugin__s2member_custom_reg_fields::validation_errors(array($field_var => $_p["ws_plugin__s2member_profile_" . $field_var]), array($field)))
114
$fields[$field_var] = $_p["ws_plugin__s2member_profile_" . $field_var];
115
else // Else ``unset()``.
116
unset($fields[$field_var]);
includes/classes/registration-times.inc.php CHANGED
@@ -18,228 +18,95 @@ if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
exit ("Do not access this file directly.");
19
20
if(!class_exists("c_ws_plugin__s2member_registration_times"))
21
{
22
/**
23
- * Registration Times.
24
*
25
* @package s2Member\Registrations
26
* @since 3.5
27
*/
28
- class c_ws_plugin__s2member_registration_times
29
{
30
- /**
31
- * Synchronizes Paid Registration Times with Role assignments.
32
- *
33
- * @package s2Member\Registrations
34
- * @since 3.5
35
- *
36
- * @attaches-to ``add_action("set_user_role");``
37
- *
38
- * @param int|str $user_id A numeric WordPress User ID should be passed in by the Action Hook.
39
- * @param str $role A WordPress Role ID/Name should be passed in by the Action Hook.
40
- *
41
- * @return null
42
- */
43
- public static function synchronize_paid_reg_times($user_id = FALSE, $role = FALSE)
44
- {
45
- foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
46
- do_action("ws_plugin__s2member_before_synchronize_paid_reg_times", get_defined_vars());
47
- unset($__refs, $__v);
48
-
49
- if($user_id && is_object($user = new WP_User ($user_id)) && !empty ($user->ID) && ($level = c_ws_plugin__s2member_user_access::user_access_level($user)) > 0)
50
- {
51
- $pr_times = get_user_option("s2member_paid_registration_times", $user_id);
52
- $pr_times["level"] = (empty ($pr_times["level"])) ? time() : $pr_times["level"];
53
- $pr_times["level".$level] = (empty ($pr_times["level".$level])) ? time() : $pr_times["level".$level];
54
- update_user_option($user_id, "s2member_paid_registration_times", $pr_times); // Update now.
55
- }
56
- }
57
-
58
- /**
59
- * Retrieves a Registration Time.
60
- *
61
- * @package s2Member\Registrations
62
- * @since 3.5
63
- *
64
- * @param int|str $user_id Optional. A numeric WordPress User ID. Defaults to the current User, if logged-in.
65
- *
66
- * @return int A Unix timestamp, indicating Registration Time, else `0` on failure.
67
- */
68
- public static function registration_time($user_id = FALSE)
69
- {
70
- foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
71
- do_action("ws_plugin__s2member_before_registration_time", get_defined_vars());
72
- unset($__refs, $__v);
73
-
74
- $user = ($user_id) ? new WP_User ($user_id) : ((is_user_logged_in()) ? wp_get_current_user() : FALSE);
75
-
76
- if(is_object($user) && !empty ($user->ID) && ($user_id = $user->ID) && $user->user_registered)
77
- {
78
- return apply_filters("ws_plugin__s2member_registration_time", strtotime($user->user_registered), get_defined_vars());
79
- }
80
- else // Else we return a default value of 0, because there is insufficient data.
81
- return apply_filters("ws_plugin__s2member_registration_time", 0, get_defined_vars());
82
- }
83
-
84
- /**
85
- * Retrieves a Paid Registration Time.
86
- *
87
- * @package s2Member\Registrations
88
- * @since 3.5
89
- *
90
- * @param int|str $level Optional. Defaults to the first/initial Paid Registration Time, regardless of Level#.
91
- * @param int|str $user_id Optional. A numeric WordPress User ID. Defaults to the current User, if logged-in.
92
- *
93
- * @return int A Unix timestamp, indicating Paid Registration Time, else `0` on failure.
94
- */
95
- public static function paid_registration_time($level = FALSE, $user_id = FALSE)
96
- {
97
- foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
98
- do_action("ws_plugin__s2member_before_paid_registration_time", get_defined_vars());
99
- unset($__refs, $__v);
100
-
101
- $level = (!is_numeric($level)) ? "level" : "level".preg_replace("/[^0-9]/", "", (string)$level);
102
- $user = ($user_id) ? new WP_User ($user_id) : ((is_user_logged_in()) ? wp_get_current_user() : FALSE);
103
-
104
- if($level && is_object($user) && !empty ($user->ID) && ($user_id = $user->ID) && is_array($pr_times = get_user_option("s2member_paid_registration_times", $user_id)))
105
- {
106
- return apply_filters("ws_plugin__s2member_paid_registration_time", ((isset ($pr_times[$level])) ? (int)$pr_times[$level] : 0), get_defined_vars());
107
- }
108
- else // Else we return a default value of `0`, because there is insufficient data.
109
- return apply_filters("ws_plugin__s2member_paid_registration_time", 0, get_defined_vars());
110
- }
111
-
112
- /**
113
- * Logs capability times.
114
- *
115
- * @package s2Member\Registrations
116
- * @since 140418
117
- *
118
- * @attaches-to ``add_action("update_user_meta")``
119
- *
120
- * @param integer $meta_id Meta row ID in database.
121
- * @param integer $object_id User ID.
122
- * @param string $meta_key Meta key.
123
- * @param mixed $meta_value Meta value.
124
- */
125
- public static function log_capability_time($meta_id, $object_id, $meta_key, $meta_value)
126
- {
127
- $wpdb = $GLOBALS["wpdb"];
128
- /** @var $wpdb \wpdb For IDEs. */
129
-
130
- if(strpos($meta_key, "capabilities") === FALSE
131
- || $meta_key !== $wpdb->get_blog_prefix()."capabilities"
132
- ) return; // Not updating caps.
133
-
134
- /*
135
- * NOTE: $prev_caps (and $new_caps) both include individual non-role caps (e.g. `access_s2member_ccap_x`).
136
- * These arrays ALSO include role names (minus role-specific caps); e.g. `administrator` or `s2member_level1`;
137
- * but NOT `delete_users` or `access_s2member_leveln`.
138
- */
139
-
140
- $user_id = $object_id;
141
- if(!is_array($new_caps = $meta_value))
142
- $new_caps = array(); // All caps removed.
143
-
144
- $user = new WP_User($user_id);
145
- if(!$user->ID || !$user->exists())
146
- return; // Not a valid user.
147
- $prev_caps = $user->caps;
148
-
149
- /*
150
- * NOTE: we iterate these arrays so that it's possible to properly analzye boolean flags.
151
- * WordPress can enable/disable a cap by adding/removing it; or by flagging it as TRUE|FALSE.
152
- */
153
- $caps_added = $caps_removed = array();
154
-
155
- foreach($new_caps as $_new_cap => $_is_enabled)
156
- if($_is_enabled && (!array_key_exists($_new_cap, $prev_caps) || !$prev_caps[$_new_cap]))
157
- $caps_added[] = $_new_cap;
158
-
159
- foreach($prev_caps as $_prev_cap => $_was_enabled)
160
- if(!array_key_exists($_prev_cap, $new_caps) || (!$new_caps[$_prev_cap] && $_was_enabled))
161
- $caps_removed[] = $_prev_cap;
162
-
163
- unset($_new_cap, $_is_enabled, $_prev_cap, $_was_enabled);
164
-
165
- /*
166
- * Below, we log CAPS that begin with:
167
- *
168
- * `s2member_level`
169
- * or `access_s2member_ccap_`
170
- *
171
- * This makes it possible for us to get access times for all s2Member Levels, and for CCAPS too.
172
- */
173
- foreach(array_unique($caps_added) as $_cap)
174
- if(strpos($_cap, "s2member_level") === 0 || strpos($_cap, "access_s2member_ccap_") === 0)
175
- c_ws_plugin__s2member_registration_times::_log_capability_time($user_id, $_cap);
176
-
177
- foreach(array_unique($caps_removed) as $_cap)
178
- if(strpos($_cap, "s2member_level") === 0 || strpos($_cap, "access_s2member_ccap_") === 0)
179
- c_ws_plugin__s2member_registration_times::_log_capability_time($user_id, $_cap, TRUE);
180
-
181
- unset($_cap); // Housekeeping.
182
- }
183
-
184
- /**
185
- * Records access times.
186
- *
187
- * @package s2Member\Registrations
188
- * @since 140418
189
- *
190
- * @param integer $user_id WP user ID.
191
- * @param integer $access_cap s2Member-related capability.
192
- * @param boolean $removed Defaults to a FALSE value. Flag as TRUE if `$access_cap` is being removed instead of being added.
193
- */
194
- public static function _log_capability_time($user_id, $access_cap, $removed = FALSE)
195
- {
196
- foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
197
- do_action("ws_plugin__s2member_before_log_capability_time", get_defined_vars());
198
- unset($__refs, $__v);
199
-
200
- if($user_id && $access_cap)
201
- {
202
- $user_id = (integer)$user_id;
203
- $ac_times = get_user_option("s2member_capability_times", $user_id);
204
- $ac_times[time()] = ($removed ? "-" : "").$access_cap;
205
- update_user_option($user_id, "s2member_capability_times", $ac_times);
206
-
207
- do_action("ws_plugin__s2member_during_log_capability_time", get_defined_vars());
208
- }
209
- do_action("ws_plugin__s2member_after_log_capability_time", get_defined_vars());
210
- }
211
-
212
- /**
213
- * Gets access capability times.
214
- *
215
- * @package s2Member\Registrations
216
- * @since 140418
217
- *
218
- * @param integer $user_id WP User ID.
219
- * @param boolean $access_caps Optional. An array of access capabilities to get the times for.
220
- * If removal times are desired, you should add a `-` prefix.
221
- *
222
- * @return array An array of all access capability times.
223
- * Keys are UTC timestamps, values are the capabilities (including `-` prefixed removals).
224
- */
225
- public static function get_capability_times($user_id, $access_caps = FALSE)
226
- {
227
- if(($user_id = (integer)$user_id))
228
- {
229
- $ac_times = get_user_option("s2member_capability_times", $user_id);
230
-
231
- if(!is_array($ac_times))
232
- $ac_times = array();
233
-
234
- else if($access_caps)
235
- $ac_times = array_intersect($ac_times, (array)$access_caps);
236
237
- ksort($ac_times);
238
- }
239
- else $ac_times = array();
240
241
- return apply_filters("ws_plugin__s2member_get_capability_times", $ac_times, get_defined_vars());
242
- }
243
}
244
}
245
- ?>
18
exit ("Do not access this file directly.");
19
20
if(!class_exists("c_ws_plugin__s2member_registration_times"))
21
+ {
22
+ /**
23
+ * Registration Times.
24
+ *
25
+ * @package s2Member\Registrations
26
+ * @since 3.5
27
+ */
28
+ class c_ws_plugin__s2member_registration_times
29
{
30
/**
31
+ * Synchronizes Paid Registration Times with Role assignments.
32
*
33
* @package s2Member\Registrations
34
* @since 3.5
35
+ *
36
+ * @attaches-to ``add_action("set_user_role");``
37
+ *
38
+ * @param integer|string $user_id A numeric WordPress User ID should be passed in by the Action Hook.
39
+ * @param string $role A WordPress Role ID/Name should be passed in by the Action Hook.
40
+ *
41
+ * @return null
42
*/
43
+ public static function synchronize_paid_reg_times($user_id = FALSE, $role = FALSE)
44
{
45
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
46
+ do_action("ws_plugin__s2member_before_synchronize_paid_reg_times", get_defined_vars());
47
+ unset($__refs, $__v);
48
+
49
+ if($user_id && is_object($user = new WP_User ($user_id)) && !empty ($user->ID) && ($level = c_ws_plugin__s2member_user_access::user_access_level($user)) > 0)
50
+ {
51
+ $pr_times = get_user_option("s2member_paid_registration_times", $user_id);
52
+ $pr_times["level"] = (empty ($pr_times["level"])) ? time() : $pr_times["level"];
53
+ $pr_times["level".$level] = (empty ($pr_times["level".$level])) ? time() : $pr_times["level".$level];
54
+ update_user_option($user_id, "s2member_paid_registration_times", $pr_times); // Update now.
55
+ }
56
+ }
57
58
+ /**
59
+ * Retrieves a Registration Time.
60
+ *
61
+ * @package s2Member\Registrations
62
+ * @since 3.5
63
+ *
64
+ * @param integer|string $user_id Optional. A numeric WordPress User ID. Defaults to the current User, if logged-in.
65
+ *
66
+ * @return int A Unix timestamp, indicating Registration Time, else `0` on failure.
67
+ */
68
+ public static function registration_time($user_id = FALSE)
69
+ {
70
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
71
+ do_action("ws_plugin__s2member_before_registration_time", get_defined_vars());
72
+ unset($__refs, $__v);
73
+
74
+ $user = ($user_id) ? new WP_User ($user_id) : ((is_user_logged_in()) ? wp_get_current_user() : FALSE);
75
+
76
+ if(is_object($user) && !empty ($user->ID) && ($user_id = $user->ID) && $user->user_registered)
77
+ {
78
+ return apply_filters("ws_plugin__s2member_registration_time", strtotime($user->user_registered), get_defined_vars());
79
+ }
80
+ else // Else we return a default value of 0, because there is insufficient data.
81
+ return apply_filters("ws_plugin__s2member_registration_time", 0, get_defined_vars());
82
+ }
83
84
+ /**
85
+ * Retrieves a Paid Registration Time.
86
+ *
87
+ * @package s2Member\Registrations
88
+ * @since 3.5
89
+ *
90
+ * @param int|string $level Optional. Defaults to the first/initial Paid Registration Time, regardless of Level#.
91
+ * @param int|string $user_id Optional. A numeric WordPress User ID. Defaults to the current User, if logged-in.
92
+ *
93
+ * @return int A Unix timestamp, indicating Paid Registration Time, else `0` on failure.
94
+ */
95
+ public static function paid_registration_time($level = FALSE, $user_id = FALSE)
96
+ {
97
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
98
+ do_action("ws_plugin__s2member_before_paid_registration_time", get_defined_vars());
99
+ unset($__refs, $__v);
100
+
101
+ $level = (!is_numeric($level)) ? "level" : "level".preg_replace("/[^0-9]/", "", (string)$level);
102
+ $user = ($user_id) ? new WP_User ($user_id) : ((is_user_logged_in()) ? wp_get_current_user() : FALSE);
103
+
104
+ if($level && is_object($user) && !empty ($user->ID) && ($user_id = $user->ID) && is_array($pr_times = get_user_option("s2member_paid_registration_times", $user_id)))
105
+ {
106
+ return apply_filters("ws_plugin__s2member_paid_registration_time", ((isset ($pr_times[$level])) ? (int)$pr_times[$level] : 0), get_defined_vars());
107
+ }
108
+ else // Else we return a default value of `0`, because there is insufficient data.
109
+ return apply_filters("ws_plugin__s2member_paid_registration_time", 0, get_defined_vars());
110
}
111
}
112
+ }
includes/classes/registrations.inc.php CHANGED
@@ -38,8 +38,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
38
*
39
* @attaches-to ``add_filter("random_password");``
40
*
41
- * @param str $password Expects a plain text Password passed through by the Filter.
42
- * @return str Password, possibly assigned through s2Member Custom Registration/Profile Field input.
43
*/
44
public static function generate_password ($password = FALSE)
45
{
@@ -60,9 +60,83 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
60
$password = $custom; // Yes, use s2Member custom Password supplied by Remote Op.
61
}
62
}
63
-
64
return apply_filters ("ws_plugin__s2member_generate_password", ($GLOBALS["ws_plugin__s2member_generate_password_return"] = $password), get_defined_vars ());
65
}
66
/**
67
* Filters Multisite User validation.
68
*
@@ -86,15 +160,17 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
86
if (is_multisite ()) // This event should ONLY be processed with Multisite Networking.
87
if (!is_admin () && isset ($result["user_name"], $result["user_email"], $result["errors"]) && ((preg_match ("/\/wp-signup\.php/", $_SERVER["REQUEST_URI"]) && !empty ($_POST["stage"]) && preg_match ("/^validate-(user|blog)-signup#x2F;", (string)$_POST["stage"])) || (c_ws_plugin__s2member_utils_conds::bp_is_installed () && bp_is_register_page ())))
88
{
89
- if (in_array ($result["errors"]->get_error_code (), array ("user_name", "user_email", "user_email_used")))
90
if (c_ws_plugin__s2member_utils_users::ms_user_login_email_exists_but_not_on_blog ($result["user_name"], $result["user_email"]))
91
- $result["errors"] = new WP_Error ();
92
-
93
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
94
do_action ("ws_plugin__s2member_during_ms_validate_user_signup", get_defined_vars ());
95
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
96
}
97
-
98
return apply_filters ("ws_plugin__s2member_ms_validate_user_signup", $result, get_defined_vars ());
99
}
100
/**
@@ -107,8 +183,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
107
* @since 3.5
108
*
109
* @attaches-to ``add_filter("signup_hidden_fields");``
110
- *
111
- * @return null
112
*/
113
public static function ms_process_signup_hidden_fields ()
114
{
@@ -124,10 +198,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
124
125
do_action ("ws_plugin__s2member_during_ms_process_signup_hidden_fields", get_defined_vars ());
126
}
127
-
128
do_action ("ws_plugin__s2member_after_ms_process_signup_hidden_fields", get_defined_vars ());
129
-
130
- return /* Return for uniformity. */;
131
}
132
/**
133
* Adds Customs Fields to ``$meta`` on signup.
@@ -167,7 +238,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
167
if ($key = preg_replace ("/_user_new_/", "_custom_reg_field_", $key))
168
$meta["s2member_ms_signup_meta"][$key] = maybe_unserialize ($value);
169
}
170
-
171
return apply_filters ("ws_plugin__s2member_ms_process_signup_meta", $meta, get_defined_vars ());
172
}
173
/**
@@ -184,9 +254,9 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
184
*
185
* @attaches-to ``add_filter("_wpmu_activate_existing_error_");``
186
*
187
- * @param obj $_error Expects a `WP_Error` object to be passed through by the Filter.
188
* @param array $vars Expects the defined variables from the scope of the calling Filter.
189
- * @return obj|array If unable to add an existing User, the original ``$_error`` obj is returned.
190
* Otherwise we return an array of User details for continued processing by the caller.
191
*/
192
public static function ms_activate_existing_user ($_error = FALSE, $vars = FALSE)
@@ -212,7 +282,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
212
return apply_filters ("ws_plugin__s2member_ms_activate_existing_user", array ("user_id" => $user_id, "password" => $password, "meta" => $meta), get_defined_vars ());
213
}
214
}
215
-
216
return apply_filters ("ws_plugin__s2member_ms_activate_existing_user", $_error, get_defined_vars ()); // Else, return the standardized error.
217
}
218
/**
@@ -227,14 +296,13 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
227
*
228
* @attaches-to ``add_action("wpmu_activate_user");``
229
*
230
- * @param int|str $user_id A numeric WordPress User ID.
231
- * @param str $password Plain text Password should be passed through by the Action Hook.
232
* @param array $meta Expects an array of ``$meta`` details, passed through by the Action Hook.
233
- * @return null
234
*/
235
public static function configure_user_on_ms_user_activation ($user_id = FALSE, $password = FALSE, $meta = FALSE)
236
{
237
- global $pagenow; // Need this to detect the current admin page.
238
239
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
240
do_action ("ws_plugin__s2member_before_configure_user_on_ms_user_activation", get_defined_vars ());
@@ -248,8 +316,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
248
}
249
250
do_action ("ws_plugin__s2member_after_configure_user_on_ms_user_activation", get_defined_vars ());
251
-
252
- return /* Return for uniformity. */;
253
}
254
/**
255
* Configures new Users on a Multisite Network installation.
@@ -266,12 +332,11 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
266
*
267
* @attaches-to ``add_action("wpmu_activate_blog");``
268
*
269
- * @param int|str $blog_id A numeric WordPress Blog ID.
270
- * @param int|str $user_id A numeric WordPress User ID.
271
- * @param str $password Plain text Password should be passed through by the Action Hook.
272
- * @param str $title The title that a User chose during signup; for their new Blog on the Network.
273
* @param array $meta Expects an array of ``$meta`` details, passed through by the Action Hook.
274
- * @return null
275
*/
276
public static function configure_user_on_ms_blog_activation ($blog_id = FALSE, $user_id = FALSE, $password = FALSE, $title = FALSE, $meta = FALSE)
277
{
@@ -285,10 +350,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
285
c_ws_plugin__s2member_registrations::configure_user_registration ($user_id, $password, ((isset ($meta["s2member_ms_signup_meta"]) && is_array ($meta["s2member_ms_signup_meta"])) ? $meta["s2member_ms_signup_meta"] : array ()));
286
delete_user_meta ($user_id, "s2member_ms_signup_meta");
287
}
288
-
289
do_action ("ws_plugin__s2member_after_configure_user_on_ms_blog_activation", get_defined_vars ());
290
-
291
- return /* Return for uniformity. */;
292
}
293
/**
294
* Intersects with ``register_new_user()`` through s2Member's Multisite Networking patch.
@@ -303,10 +365,10 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
303
*
304
* @attaches-to ``add_filter("registration_errors");``
305
*
306
- * @param obj $errors Expects a `WP_Error` object passed in by the Filter.
307
- * @param str $user_login Expects the User's Username, passed in by the Filter.
308
- * @param str $user_email Expects the User's Email Address, passed in by the Filter.
309
- * @return obj A `WP_Error` object, or exits script execution after handling registration redirection.
310
*/
311
public static function ms_register_existing_user ($errors = FALSE, $user_login = FALSE, $user_email = FALSE)
312
{
@@ -354,10 +416,10 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
354
* @package s2Member\Registrations
355
* @since 3.5
356
*
357
- * @param str $user_login Expects the User's Username.
358
- * @param str $user_email Expects the User's Email Address.
359
- * @param str $user_pass Expects the User's plain text Password.
360
- * @param int|str $user_id Optional. A numeric WordPress User ID.
361
* If unspecified, a lookup is performed with ``$user_login`` and ``$user_email``.
362
* @return int|false Returns numeric ``$user_id`` on success, else false on failure.
363
*/
@@ -381,7 +443,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
381
return apply_filters ("ws_plugin__s2member_ms_create_existing_user", $user_id, get_defined_vars ());
382
}
383
}
384
-
385
return apply_filters ("ws_plugin__s2member_ms_create_existing_user", false, get_defined_vars ());
386
}
387
/**
@@ -398,12 +459,11 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
398
*
399
* @attaches-to ``add_action("user_register");``
400
*
401
- * @param int|str $user_id A numeric WordPress User ID.
402
- * @param str $password Optional in most cases. A User's plain text Password. If unspecified, attempts are made to collect the plain text Password from other sources.
403
* @param array $meta Optional in most cases. Defaults to false. An array of meta data for a User/Member.
404
- * @return null No return value. Returns `null` in possible every scenario.
405
*
406
- * @todo Impossible to delete cookies when fired inside: `/wp-activate.php`?
407
*/
408
public static function configure_user_registration ($user_id = FALSE, $password = FALSE, $meta = FALSE)
409
{
@@ -1043,9 +1103,6 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
1043
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
1044
do_action ("ws_plugin__s2member_after_configure_user_registration", get_defined_vars ());
1045
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
1046
-
1047
- return /* Return for uniformity. */;
1048
}
1049
}
1050
- }
1051
- ?>
38
*
39
* @attaches-to ``add_filter("random_password");``
40
*
41
+ * @param string $password Expects a plain text Password passed through by the Filter.
42
+ * @return string Password, possibly assigned through s2Member Custom Registration/Profile Field input.
43
*/
44
public static function generate_password ($password = FALSE)
45
{
60
$password = $custom; // Yes, use s2Member custom Password supplied by Remote Op.
61
}
62
}
63
return apply_filters ("ws_plugin__s2member_generate_password", ($GLOBALS["ws_plugin__s2member_generate_password_return"] = $password), get_defined_vars ());
64
}
65
+
66
+ /**
67
+ * Intersects with ``register_new_user()`` in the WordPress core.
68
+ *
69
+ * This function Filters registration errors inside `/wp-login.php` via ``register_new_user()``.
70
+ *
71
+ * This can ONLY be fired through `/wp-login.php` on the front-side.
72
+ *
73
+ * @package s2Member\Registrations
74
+ * @since 140518
75
+ *
76
+ * @attaches-to ``add_filter("registration_errors");``
77
+ *
78
+ * @param WP_Error $errors Expects a `WP_Error` object passed in by the Filter.
79
+ * @param string $user_login Expects the User's Username, passed in by the Filter.
80
+ * @param string $user_email Expects the User's Email Address, passed in by the Filter.
81
+ * @return WP_Error A `WP_Error` object instance.
82
+ */
83
+ public static function custom_registration_field_errors($errors = FALSE, $user_login = FALSE, $user_email = FALSE)
84
+ {
85
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
86
+ do_action("ws_plugin__s2member_before_custom_registration_field_errors", get_defined_vars());
87
+ unset /* Unset defined __refs, __v. */ ($__refs, $__v);
88
+
89
+ if (!is_admin () && preg_match ("/\/wp-login\.php/", $_SERVER["REQUEST_URI"]))
90
+ if (is_wp_error ($errors) && !empty ($_POST) && is_array ($_POST))
91
+ {
92
+ foreach(c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_POST)) as $_key => $_value)
93
+ if(strpos($_key, "ws_plugin__s2member_custom_reg_field_") === 0)
94
+ $input[str_replace("ws_plugin__s2member_custom_reg_field_", "", $_key)] = $_value;
95
+
96
+ $fields_to_validate = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level("auto-detection", "registration", TRUE);
97
+ $validation_errors = c_ws_plugin__s2member_custom_reg_fields::validation_errors(!empty($input) ? $input : array(), $fields_to_validate);
98
+
99
+ if($validation_errors) foreach($validation_errors as $_field_var => $_error)
100
+ $errors->add("custom_reg_field_".$_field_var, $_error);
101
+ unset($_field_var, $_error);
102
+ }
103
+ return apply_filters ("ws_plugin__s2member_custom_registration_field_errors", $errors, get_defined_vars ());
104
+ }
105
+
106
+ /**
107
+ * Intersects with ``bp_core_screen_signup()`` in the BuddyPress core.
108
+ *
109
+ * This can ONLY be fired through `/register` via BuddyPress.
110
+ *
111
+ * @package s2Member\Registrations
112
+ * @since 140518
113
+ *
114
+ * @attaches-to ``add_action("bp_signup_validate");``
115
+ */
116
+ public static function custom_registration_field_errors_4bp()
117
+ {
118
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
119
+ do_action("ws_plugin__s2member_before_custom_registration_field_errors_4bp", get_defined_vars());
120
+ unset /* Unset defined __refs, __v. */ ($__refs, $__v);
121
+
122
+ if (!is_admin () && c_ws_plugin__s2member_utils_conds::bp_is_installed () && bp_is_register_page ())
123
+ if(in_array ("registration", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields_4bp"]))
124
+ if(apply_filters ("ws_plugin__s2member_custom_registration_fields_4bp_display", true, get_defined_vars ()))
125
+ if (!empty($GLOBALS["bp"]->signup) && is_object($GLOBALS["bp"]->signup) && !empty ($_POST) && is_array ($_POST))
126
+ {
127
+ foreach(c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_POST)) as $_key => $_value)
128
+ if(strpos($_key, "ws_plugin__s2member_custom_reg_field_") === 0)
129
+ $input[str_replace("ws_plugin__s2member_custom_reg_field_", "", $_key)] = $_value;
130
+
131
+ $fields_to_validate = c_ws_plugin__s2member_custom_reg_fields::custom_fields_configured_at_level("auto-detection", "registration", TRUE);
132
+ $validation_errors = c_ws_plugin__s2member_custom_reg_fields::validation_errors(!empty($input) ? $input : array(), $fields_to_validate);
133
+
134
+ if($validation_errors) foreach($validation_errors as $_field_var => $_error)
135
+ $GLOBALS["bp"]->signup->errors["custom_reg_field_".$_field_var] = $_error;
136
+ unset($_field_var, $_error);
137
+ }
138
+ }
139
+
140
/**
141
* Filters Multisite User validation.
142
*
160
if (is_multisite ()) // This event should ONLY be processed with Multisite Networking.
161
if (!is_admin () && isset ($result["user_name"], $result["user_email"], $result["errors"]) && ((preg_match ("/\/wp-signup\.php/", $_SERVER["REQUEST_URI"]) && !empty ($_POST["stage"]) && preg_match ("/^validate-(user|blog)-signup#x2F;", (string)$_POST["stage"])) || (c_ws_plugin__s2member_utils_conds::bp_is_installed () && bp_is_register_page ())))
162
{
163
+ $errors =& $result["errors"]; /** @var $errors WP_Error */
164
+ if (in_array ($errors->get_error_code (), array ("user_name", "user_email", "user_email_used")))
165
if (c_ws_plugin__s2member_utils_users::ms_user_login_email_exists_but_not_on_blog ($result["user_name"], $result["user_email"]))
166
+ {
167
+ unset($errors->errors["user_name"], $errors->errors["user_email"], $errors->errors["user_email_used"]);
168
+ unset($errors->error_data["user_name"], $errors->error_data["user_email"], $errors->error_data["user_email_used"]);
169
+ }
170
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
171
do_action ("ws_plugin__s2member_during_ms_validate_user_signup", get_defined_vars ());
172
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
173
}
174
return apply_filters ("ws_plugin__s2member_ms_validate_user_signup", $result, get_defined_vars ());
175
}
176
/**
183
* @since 3.5
184
*
185
* @attaches-to ``add_filter("signup_hidden_fields");``
186
*/
187
public static function ms_process_signup_hidden_fields ()
188
{
198
199
do_action ("ws_plugin__s2member_during_ms_process_signup_hidden_fields", get_defined_vars ());
200
}
201
do_action ("ws_plugin__s2member_after_ms_process_signup_hidden_fields", get_defined_vars ());
202
}
203
/**
204
* Adds Customs Fields to ``$meta`` on signup.
238
if ($key = preg_replace ("/_user_new_/", "_custom_reg_field_", $key))
239
$meta["s2member_ms_signup_meta"][$key] = maybe_unserialize ($value);
240
}
241
return apply_filters ("ws_plugin__s2member_ms_process_signup_meta", $meta, get_defined_vars ());
242
}
243
/**
254
*
255
* @attaches-to ``add_filter("_wpmu_activate_existing_error_");``
256
*
257
+ * @param WP_Error $_error Expects a `WP_Error` object to be passed through by the Filter.
258
* @param array $vars Expects the defined variables from the scope of the calling Filter.
259
+ * @return WP_Error|array If unable to add an existing User, the original ``$_error`` obj is returned.
260
* Otherwise we return an array of User details for continued processing by the caller.
261
*/
262
public static function ms_activate_existing_user ($_error = FALSE, $vars = FALSE)
282
return apply_filters ("ws_plugin__s2member_ms_activate_existing_user", array ("user_id" => $user_id, "password" => $password, "meta" => $meta), get_defined_vars ());
283
}
284
}
285
return apply_filters ("ws_plugin__s2member_ms_activate_existing_user", $_error, get_defined_vars ()); // Else, return the standardized error.
286
}
287
/**
296
*
297
* @attaches-to ``add_action("wpmu_activate_user");``
298
*
299
+ * @param int|string $user_id A numeric WordPress User ID.
300
+ * @param string $password Plain text Password should be passed through by the Action Hook.
301
* @param array $meta Expects an array of ``$meta`` details, passed through by the Action Hook.
302
*/
303
public static function configure_user_on_ms_user_activation ($user_id = FALSE, $password = FALSE, $meta = FALSE)
304
{
305
+ global $pagenow; // Detect the current admin page.
306
307
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
308
do_action ("ws_plugin__s2member_before_configure_user_on_ms_user_activation", get_defined_vars ());
316
}
317
318
do_action ("ws_plugin__s2member_after_configure_user_on_ms_user_activation", get_defined_vars ());
319
}
320
/**
321
* Configures new Users on a Multisite Network installation.
332
*
333
* @attaches-to ``add_action("wpmu_activate_blog");``
334
*
335
+ * @param int|string $blog_id A numeric WordPress Blog ID.
336
+ * @param int|string $user_id A numeric WordPress User ID.
337
+ * @param string $password Plain text Password should be passed through by the Action Hook.
338
+ * @param string $title The title that a User chose during signup; for their new Blog on the Network.
339
* @param array $meta Expects an array of ``$meta`` details, passed through by the Action Hook.
340
*/
341
public static function configure_user_on_ms_blog_activation ($blog_id = FALSE, $user_id = FALSE, $password = FALSE, $title = FALSE, $meta = FALSE)
342
{
350
c_ws_plugin__s2member_registrations::configure_user_registration ($user_id, $password, ((isset ($meta["s2member_ms_signup_meta"]) && is_array ($meta["s2member_ms_signup_meta"])) ? $meta["s2member_ms_signup_meta"] : array ()));
351
delete_user_meta ($user_id, "s2member_ms_signup_meta");
352
}
353
do_action ("ws_plugin__s2member_after_configure_user_on_ms_blog_activation", get_defined_vars ());
354
}
355
/**
356
* Intersects with ``register_new_user()`` through s2Member's Multisite Networking patch.
365
*
366
* @attaches-to ``add_filter("registration_errors");``
367
*
368
+ * @param WP_Error $errors Expects a `WP_Error` object passed in by the Filter.
369
+ * @param string $user_login Expects the User's Username, passed in by the Filter.
370
+ * @param string $user_email Expects the User's Email Address, passed in by the Filter.
371
+ * @return WP_Error A `WP_Error` object, or exits script execution after handling registration redirection.
372
*/
373
public static function ms_register_existing_user ($errors = FALSE, $user_login = FALSE, $user_email = FALSE)
374
{
416
* @package s2Member\Registrations
417
* @since 3.5
418
*
419
+ * @param string $user_login Expects the User's Username.
420
+ * @param string $user_email Expects the User's Email Address.
421
+ * @param string $user_pass Expects the User's plain text Password.
422
+ * @param int|string $user_id Optional. A numeric WordPress User ID.
423
* If unspecified, a lookup is performed with ``$user_login`` and ``$user_email``.
424
* @return int|false Returns numeric ``$user_id`` on success, else false on failure.
425
*/
443
return apply_filters ("ws_plugin__s2member_ms_create_existing_user", $user_id, get_defined_vars ());
444
}
445
}
446
return apply_filters ("ws_plugin__s2member_ms_create_existing_user", false, get_defined_vars ());
447
}
448
/**
459
*
460
* @attaches-to ``add_action("user_register");``
461
*
462
+ * @param int|string $user_id A numeric WordPress User ID.
463
+ * @param string $password Optional in most cases. A User's plain text Password. If unspecified, attempts are made to collect the plain text Password from other sources.
464
* @param array $meta Optional in most cases. Defaults to false. An array of meta data for a User/Member.
465
*
466
+ * @TODO Impossible to delete cookies when fired inside: `/wp-activate.php`?
467
*/
468
public static function configure_user_registration ($user_id = FALSE, $password = FALSE, $meta = FALSE)
469
{
1103
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
1104
do_action ("ws_plugin__s2member_after_configure_user_registration", get_defined_vars ());
1105
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
1106
}
1107
}
1108
+ }
includes/classes/return-templates.inc.php CHANGED
@@ -36,7 +36,7 @@ if (!class_exists ("c_ws_plugin__s2member_return_templates"))
36
* @param str $template Optional A Subscr. Gateway code should be used as the template name, or `default` is a multipurpose template. Defaults to `default`. Used in template selection.
37
* @param str $response Optional. Response message to fill template with, using the Replacement Code `%%response%%` inside the template file. Defaults to: `Thank you. Please click the link below.`.
38
* @param str $continue_html Optional. The HTML value of the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: `Continue`.
39
- * @param str $continue_link Optional. The HREF value for the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: ``home_url ("/")``.
40
* @return str The full HTML code of the template. All Replacement Codes inside the template file will have already been filled by this routine.
41
*/
42
public static function return_template ($template = FALSE, $response = FALSE, $continue_html = FALSE, $continue_link = FALSE)
@@ -46,7 +46,7 @@ if (!class_exists ("c_ws_plugin__s2member_return_templates"))
46
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
47
48
$template = ($template) ? $template : "default";
49
- $continue_link = ($continue_link) ? $continue_link : home_url ("/");
50
$continue_html = ($continue_html) ? $continue_html : _x ("Continue", "s2member-front", "s2member");
51
$response = ($response) ? $response : _x ("Thank you. Please click the link below.", "s2member-front", "s2member");
52
36
* @param str $template Optional A Subscr. Gateway code should be used as the template name, or `default` is a multipurpose template. Defaults to `default`. Used in template selection.
37
* @param str $response Optional. Response message to fill template with, using the Replacement Code `%%response%%` inside the template file. Defaults to: `Thank you. Please click the link below.`.
38
* @param str $continue_html Optional. The HTML value of the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: `Continue`.
39
+ * @param str $continue_link Optional. The HREF value for the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: ``home_url ("/", "http")``.
40
* @return str The full HTML code of the template. All Replacement Codes inside the template file will have already been filled by this routine.
41
*/
42
public static function return_template ($template = FALSE, $response = FALSE, $continue_html = FALSE, $continue_link = FALSE)
46
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
47
48
$template = ($template) ? $template : "default";
49
+ $continue_link = ($continue_link) ? $continue_link : home_url ("/", "http");
50
$continue_html = ($continue_html) ? $continue_html : _x ("Continue", "s2member-front", "s2member");
51
$response = ($response) ? $response : _x ("Thank you. Please click the link below.", "s2member-front", "s2member");
52
includes/classes/user-deletions.inc.php CHANGED
@@ -118,7 +118,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_deletions"))
118
119
delete_user_option ($user_id, "s2member_ipn_signup_vars");
120
delete_user_option ($user_id, "s2member_paid_registration_times");
121
- delete_user_option ($user_id, "s2member_capability_times");
122
delete_user_option ($user_id, "s2member_sp_references");
123
124
delete_user_option ($user_id, "s2member_last_status_scan");
118
119
delete_user_option ($user_id, "s2member_ipn_signup_vars");
120
delete_user_option ($user_id, "s2member_paid_registration_times");
121
+ delete_user_option ($user_id, "s2member_access_cap_times");
122
delete_user_option ($user_id, "s2member_sp_references");
123
124
delete_user_option ($user_id, "s2member_last_status_scan");
includes/classes/user-drip-access.inc.php ADDED
@@ -0,0 +1,147 @@
1
+ <?php
2
+ /**
3
+ * User drip access routines.
4
+ *
5
+ * Copyright: © 2009-2014 (coded in the USA)
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ *
8
+ * Released under the terms of the GNU General Public License.
9
+ * You should have received a copy of the GNU General Public License,
10
+ * along with this software. In the main directory, see: /licensing/
11
+ * If not, see: {@link http://www.gnu.org/licenses/}.
12
+ *
13
+ * @package s2Member\User_Drip_Access
14
+ * @since 140514
15
+ */
16
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
17
+ exit ('Do not access this file directly.');
18
+
19
+ if(!class_exists('c_ws_plugin__s2member_user_drip_access'))
20
+ {
21
+ /**
22
+ * User drip access routines.
23
+ *
24
+ * @package s2Member\User_Drip_Access
25
+ * @since 140514
26
+ *
27
+ * @note MUST use `self::` instead of `static::` for PHP v5.2 compat.
28
+ */
29
+ class c_ws_plugin__s2member_user_drip_access
30
+ {
31
+ /**
32
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
33
+ * @var integer Current `$from_day`; used by callback.
34
+ */
35
+ protected static $from_day = 0;
36
+
37
+ /**
38
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
39
+ * @var integer Current `$to_day`; used by callback.
40
+ */
41
+ protected static $to_day = 0;
42
+
43
+ /**
44
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
45
+ * @var integer Current `$user_id`; used by callback.
46
+ */
47
+ protected static $user_id = 0;
48
+
49
+ /**
50
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
51
+ * @var array Current array of paid times for {@link $user_id}.
52
+ */
53
+ protected static $all_paid_reg_times = array();
54
+
55
+ /**
56
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
57
+ * @var array Current array of access capability times for {@link $user_id}.
58
+ */
59
+ protected static $all_access_cap_times = array();
60
+
61
+ /**
62
+ * Conditional check for drip access.
63
+ *
64
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
65
+ *
66
+ * @param string $access Required; conditional expression with access_s2member_ capabilities
67
+ * (i.e. leveln, ccap_name), e.g. `level2` or `level3 and (ccap_music or ccap_videos)`.
68
+ * Note that `and`, `or` MUST be used in place of `&&`, `||` due to sanitation routines.
69
+ * The `$access` string may contain only `[A-Za-z0-9 _()]`.
70
+ *
71
+ * @param integer $from_day Optional. Defaults to `0`. Any value greater than or equal to `0`.
72
+ * @param integer $to_day Optional. Defaults to `0`. Any value greater than or equal to `0`.
73
+ *
74
+ * @param null|integer $user_id Optional. A `NULL` value indicates the current user.
75
+ *
76
+ * @return boolean `TRUE` if user can `$access`; and dripping should occur; based on `$from_day` & `$to_day`.
77
+ *
78
+ * @triggers `E_USER_ERROR` if an invalid `$access` syntax is detected; with invalid chars.
79
+ * @triggers `E_USER_ERROR` if an invalid `$access` syntax is detected; without any word chars.
80
+ */
81
+ public static function user_can_access_drip($access, $from_day = 0, $to_day = 0, $user_id = NULL)
82
+ {
83
+ $drip = FALSE;
84
+ $access = trim((string)$access);
85
+ $from_day = self::$from_day = (integer)$from_day;
86
+ $to_day = self::$to_day = (integer)$to_day;
87
+
88
+ if(!isset($user_id))
89
+ $user_id = get_current_user_id();
90
+ $user_id = self::$user_id = (integer)$user_id;
91
+
92
+ if(user_can($user_id, 'administrator'))
93
+ $drip = TRUE;
94
+
95
+ else if($access && $user_id)
96
+ {
97
+ if(!is_array($all_access_cap_times = self::$all_access_cap_times = c_ws_plugin__s2member_access_cap_times::get_access_cap_times($user_id)))
98
+ $all_access_cap_times = self::$all_access_cap_times = array();
99
+
100
+ $access_expression = strtolower($access); // e.g. 'level1 and ccap_music'
101
+ $access_expression = trim(preg_replace('/[^a-z0-9 _()]/', '', $access_expression, -1, $invalid_chars));
102
+ $access_expression = str_replace(array(' and ', ' or '), array(' && ', ' || '), $access_expression);
103
+
104
+ if($invalid_chars)
105
+ trigger_error('Syntax error: invalid chars. Please use only `A-Za-z0-9 _()` in the `access` parameter of s2Drip.', E_USER_ERROR);
106
+
107
+ if(!$access_expression || !preg_match('/\w+/', $access_expression))
108
+ trigger_error('Syntax error: no word chars in `access` parameter of s2Drip. Valid example: `level1 and ccap_music`.', E_USER_ERROR);
109
+
110
+ $access_expression = preg_replace_callback('/\w+/', 'self::_user_can_access_drip_cb', $access_expression);
111
+ $drip = eval('return ('.$access_expression.');');
112
+ }
113
+ return apply_filters('ws_plugin__s2member_user_can_access_drip', $drip, get_defined_vars());
114
+ }
115
+
116
+ /**
117
+ * Conditional check for drip access (callback).
118
+ *
119
+ * @since 140514 Enhancing `[s2Drip]` shortcode.
120
+ *
121
+ * @param array $cap Regex matches passed via {@link \preg_replace_callback()}.
122
+ *
123
+ * @return string One of `TRUE` or `FALSE`; as a string value.
124
+ */
125
+ protected static function _user_can_access_drip_cb($cap)
126
+ {
127
+ $drip = 'FALSE';
128
+ $cap = (string)$cap[0];
129
+
130
+ if($cap && user_can(self::$user_id, 'access_s2member_'.$cap))
131
+ {
132
+ $time = time();
133
+ $cap_times = array_keys(self::$all_access_cap_times, $cap, TRUE);
134
+ $cap_time_latest = $cap_times ? max($cap_times) : 0;
135
+
136
+ if($cap_time_latest && $time > ($cap_time_latest + (max(0, (self::$from_day - 1)) * 86400)))
137
+ {
138
+ $drip = 'TRUE'; // At/after $from_day.
139
+ if(self::$to_day > 0 && $time > ($cap_time_latest + (self::$to_day * 86400)))
140
+ $drip = 'FALSE'; // After $to_day.
141
+ }
142
+ }
143
+
144
+ return apply_filters('ws_plugin__s2member_user_can_access_drip_cb', $drip, get_defined_vars());
145
+ }
146
+ }
147
+ }
includes/classes/users-list.inc.php CHANGED
@@ -36,7 +36,7 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
36
* @attaches-to ``add_action("edit_user_profile");``
37
* @attaches-to ``add_action("show_user_profile");``
38
*
39
- * @param obj $user Expects a `WP_User` object passed in by the Action Hook.
40
* @return inner Return-value of inner routine.
41
*/
42
public static function users_list_edit_cols ($user = FALSE)
@@ -52,7 +52,7 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
52
* @attaches-to ``add_action("edit_user_profile_update");``
53
* @attaches-to ``add_action("personal_options_update");``
54
*
55
- * @param int|str $user_id Expects a numeric WordPress User ID passed in by the Action Hook.
56
* @return inner Return-value of inner routine.
57
*/
58
public static function users_list_update_cols ($user_id = FALSE)
@@ -69,12 +69,11 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
69
*
70
* @attaches-to ``add_action("pre_user_query");``
71
*
72
- * @param obj $query Expects a `WP_User_Query` object, by reference.
73
- * @return null After possibly modifying the ``$query`` object.
74
*/
75
public static function users_list_query (&$query = FALSE)
76
{
77
- global $wpdb; // Need this global object reference.
78
79
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
80
do_action ("ws_plugin__s2member_before_users_list_search", get_defined_vars ());
@@ -106,8 +105,6 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
106
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
107
do_action ("ws_plugin__s2member_after_users_list_search", get_defined_vars ());
108
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
109
-
110
- return /* Return for uniformity. */;
111
}
112
/**
113
* Adds columns to the list of Users.
@@ -165,10 +162,10 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
165
*
166
* @attaches-to ``add_filter ("manage_users_custom_column");``
167
*
168
- * @param str $val A value for this column, passed through by the Filter.
169
- * @param str $col The name of the column for which we might need to supply data for.
170
- * @param int|str $user_id Expects a WordPress User ID, passed through by the Filter.
171
- * @return str A column value introduced by this routine, or existing value, or, if empty, a dash.
172
*/
173
public static function users_list_display_cols ($val = FALSE, $col = FALSE, $user_id = FALSE)
174
{
@@ -198,7 +195,6 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
198
$val .= (($val) ? "<br />" : "") . '<small><em>@Level ' . esc_html ($level) . ': <span title="' . esc_attr (date ("D M jS, Y", $time)) . ' @ precisely ' . esc_attr (date ("g:i a", $time)) . '">' . esc_html (date ("D M jS, Y", $time)) . '</span></em></small>';
199
}
200
}
201
-
202
else if ($col === "s2member_subscr_id")
203
$val = ($v = get_user_option ("s2member_subscr_id", $user_id)) ? esc_html ($v) : "—";
204
@@ -231,7 +227,6 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
231
232
$last_fields_id = $user_id; // Record this.
233
}
234
-
235
else if ($col === "s2member_login_counter")
236
$val = ($v = get_user_option ("s2member_login_counter", $user_id)) ? esc_html ($v) : "—";
237
@@ -248,6 +243,61 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
248
249
return apply_filters ("ws_plugin__s2member_users_list_display_cols", ((strlen ($val)) ? $val : "—"), get_defined_vars ());
250
}
251
}
252
- }
253
- ?>
36
* @attaches-to ``add_action("edit_user_profile");``
37
* @attaches-to ``add_action("show_user_profile");``
38
*
39
+ * @param WP_User $user Expects a `WP_User` object passed in by the Action Hook.
40
* @return inner Return-value of inner routine.
41
*/
42
public static function users_list_edit_cols ($user = FALSE)
52
* @attaches-to ``add_action("edit_user_profile_update");``
53
* @attaches-to ``add_action("personal_options_update");``
54
*
55
+ * @param int|string $user_id Expects a numeric WordPress User ID passed in by the Action Hook.
56
* @return inner Return-value of inner routine.
57
*/
58
public static function users_list_update_cols ($user_id = FALSE)
69
*
70
* @attaches-to ``add_action("pre_user_query");``
71
*
72
+ * @param WP_User_Query $query Expects a `WP_User_Query` object, by reference.
73
*/
74
public static function users_list_query (&$query = FALSE)
75
{
76
+ global $wpdb; /** @var $wpdb wpdb */
77
78
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
79
do_action ("ws_plugin__s2member_before_users_list_search", get_defined_vars ());
105
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
106
do_action ("ws_plugin__s2member_after_users_list_search", get_defined_vars ());
107
unset /* Unset defined __refs, __v. */ ($__refs, $__v);
108
}
109
/**
110
* Adds columns to the list of Users.
162
*
163
* @attaches-to ``add_filter ("manage_users_custom_column");``
164
*
165
+ * @param string $val A value for this column, passed through by the Filter.
166
+ * @param string $col The name of the column for which we might need to supply data for.
167
+ * @param int|string $user_id Expects a WordPress User ID, passed through by the Filter.
168
+ * @return string A column value introduced by this routine, or existing value, or, if empty, a dash.
169
*/
170
public static function users_list_display_cols ($val = FALSE, $col = FALSE, $user_id = FALSE)
171
{
195
$val .= (($val) ? "<br />" : "") . '<small><em>@Level ' . esc_html ($level) . ': <span title="' . esc_attr (date ("D M jS, Y", $time)) . ' @ precisely ' . esc_attr (date ("g:i a", $time)) . '">' . esc_html (date ("D M jS, Y", $time)) . '</span></em></small>';
196
}
197
}
198
else if ($col === "s2member_subscr_id")
199
$val = ($v = get_user_option ("s2member_subscr_id", $user_id)) ? esc_html ($v) : "—";
200
227
228
$last_fields_id = $user_id; // Record this.
229
}
230
else if ($col === "s2member_login_counter")
231
$val = ($v = get_user_option ("s2member_login_counter", $user_id)) ? esc_html ($v) : "—";
232
243
244
return apply_filters ("ws_plugin__s2member_users_list_display_cols", ((strlen ($val)) ? $val : "—"), get_defined_vars ());
245
}
246
+
247
+ /**
248
+ * Tells WordPress certain fields s2Member adds are sortable
249
+ *
250
+ * @package s2Member\Users_List
251
+ * @since 140518
252
+ *
253
+ * @attaches-to ``add_filter ("manage_users_sortable_columns");``
254
+ *
255
+ * @param array $columns An Array of sortable User List Columns
256
+ */
257
+ public static function users_list_add_sortable($columns)
258
+ {
259
+ $columns['s2member_registration_time'] = 's2member_registration_time';
260
+ $columns['s2member_subscr_id'] = 's2member_subscr_id';
261
+ $columns['s2member_auto_eot_time'] = 's2member_auto_eot_time';
262
+ $columns['s2member_login_counter'] = 's2member_login_counter';
263
+ $columns['s2member_last_login_time'] = 's2member_last_login_time';
264
+ return $columns;
265
+ }
266
+
267
+ /**
268
+ * Alters WP_Query object to make custom columns sortable
269
+ *
270
+ * @package s2Member\Users_List
271
+ * @since 140518
272
+ *
273
+ * @attaches-to ``add_filter ("pre_user_query");``
274
+ *
275
+ * @param WP_User_Query $query `WP_Query` Object passed from WordPress
276
+ */
277
+ public static function users_list_make_sortable($query)
278
+ {
279
+ if (!is_admin()
280
+ || empty($GLOBALS['pagenow']) || $GLOBALS['pagenow'] !== 'users.php'
281
+ || !isset ($query->query_vars))
282
+ return;
283
+
284
+ global $wpdb; /** @var $wpdb wpdb */
285
+ $vars = $query->query_vars;
286
+
287
+ switch($vars['orderby'])
288
+ {
289
+ case 's2member_registration_time':
290
+ $query->query_orderby = "ORDER BY `user_registered` " . $vars['order'];
291
+ break;
292
+
293
+ case 's2member_subscr_id':
294
+ case 's2member_auto_eot_time':
295
+ case 's2member_login_counter':
296
+ case 's2member_last_login_time':
297
+ $query->query_from .= " LEFT JOIN `" . $wpdb->usermeta . "` `m` ON (" . $wpdb->users . ".`ID` = `m`.`user_id` AND `m`.`meta_key` = '" . esc_sql($wpdb->prefix . $vars['orderby']) . "')";
298
+ $query->query_orderby = "ORDER BY `m`.`meta_value` " . $vars['order'];
299
+ break;
300
+ }
301
+ }
302
}
303
+ }
includes/classes/utils-users.inc.php CHANGED
@@ -37,7 +37,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
37
*/
38
public static function users_in_database ()
39
{
40
- global /* Global database object reference. */ $wpdb;
41
42
$q1 = mysql_query ("SELECT SQL_CALC_FOUND_ROWS `" . $wpdb->users . "`.`ID` FROM `" . $wpdb->users . "`, `" . $wpdb->usermeta . "` WHERE `" . $wpdb->users . "`.`ID` = `" . $wpdb->usermeta . "`.`user_id` AND `" . $wpdb->usermeta . "`.`meta_key` = '" . esc_sql ($wpdb->prefix . "capabilities") . "' LIMIT 1", $wpdb->dbh);
43
$q2 = mysql_query ("SELECT FOUND_ROWS()", $wpdb->dbh);
@@ -63,7 +63,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
63
*/
64
public static function get_user_custom_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
65
{
66
- global /* Need global DB obj. */ $wpdb;
67
68
if /* This case includes some additional routines that can use the ``$os0`` value. */ ($subscr_or_txn_id && $os0)
69
{
@@ -94,7 +94,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
94
*/
95
public static function get_user_id_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
96
{
97
- global /* Need global DB obj. */ $wpdb;
98
99
if /* This case includes some additional routines that can use the ``$os0`` value. */($subscr_or_txn_id && $os0)
100
{
@@ -123,7 +123,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
123
*/
124
public static function get_user_email_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
125
{
126
- global /* Need global DB obj. */ $wpdb;
127
128
if /* This case includes some additional routines that can use the ``$os0`` value. */($subscr_or_txn_id && $os0)
129
{
@@ -228,7 +228,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
228
*/
229
public static function user_login_email_exists ($user_login = FALSE, $user_email = FALSE)
230
{
231
- global /* Global database object reference. */ $wpdb;
232
233
if /* Only if we have both of these. */ ($user_login && $user_email)
234
if (($user_id = $wpdb->get_var ("SELECT `ID` FROM `" . $wpdb->users . "` WHERE `user_login` LIKE '" . esc_sql (like_escape ($user_login)) . "' AND `user_email` LIKE '" . esc_sql (like_escape ($user_email)) . "' LIMIT 1")))
@@ -295,7 +295,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_users"))
295
*/
296
public static function get_user_field ($field_id = FALSE, $user_id = FALSE) // Very powerful function here.
297
{
298
- global /* Global database object reference. */ $wpdb;
299
300
$current_user = /* Current User's object (used when/if `$user_id` is empty). */ wp_get_current_user ();
301
37
*/
38
public static function users_in_database ()
39
{
40
+ global $wpdb; /** @var $wpdb \wpdb */
41
42
$q1 = mysql_query ("SELECT SQL_CALC_FOUND_ROWS `" . $wpdb->users . "`.`ID` FROM `" . $wpdb->users . "`, `" . $wpdb->usermeta . "` WHERE `" . $wpdb->users . "`.`ID` = `" . $wpdb->usermeta . "`.`user_id` AND `" . $wpdb->usermeta . "`.`meta_key` = '" . esc_sql ($wpdb->prefix . "capabilities") . "' LIMIT 1", $wpdb->dbh);
43
$q2 = mysql_query ("SELECT FOUND_ROWS()", $wpdb->dbh);
63
*/
64
public static function get_user_custom_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
65
{
66
+ global $wpdb; /** @var $wpdb \wpdb */
67
68
if /* This case includes some additional routines that can use the ``$os0`` value. */ ($subscr_or_txn_id && $os0)
69
{
94
*/
95
public static function get_user_id_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
96
{
97
+ global $wpdb; /** @var $wpdb \wpdb */
98
99
if /* This case includes some additional routines that can use the ``$os0`` value. */($subscr_or_txn_id && $os0)
100
{
123
*/
124
public static function get_user_email_with ($subscr_or_txn_id = FALSE, $os0 = FALSE)
125
{
126
+ global $wpdb; /** @var $wpdb \wpdb */
127
128
if /* This case includes some additional routines that can use the ``$os0`` value. */($subscr_or_txn_id && $os0)
129
{
228
*/
229
public static function user_login_email_exists ($user_login = FALSE, $user_email = FALSE)
230
{
231
+ global $wpdb; /** @var $wpdb \wpdb */
232
233
if /* Only if we have both of these. */ ($user_login && $user_email)
234
if (($user_id = $wpdb->get_var ("SELECT `ID` FROM `" . $wpdb->users . "` WHERE `user_login` LIKE '" . esc_sql (like_escape ($user_login)) . "' AND `user_email` LIKE '" . esc_sql (like_escape ($user_email)) . "' LIMIT 1")))
295
*/
296
public static function get_user_field ($field_id = FALSE, $user_id = FALSE) // Very powerful function here.
297
{
298
+ global $wpdb; /** @var $wpdb \wpdb */
299
300
$current_user = /* Current User's object (used when/if `$user_id` is empty). */ wp_get_current_user ();
301
includes/functions/api-functions.inc.php CHANGED
@@ -2245,13 +2245,36 @@ if(!function_exists("s2member_paid_registration_time"))
2245
return c_ws_plugin__s2member_registration_times::paid_registration_time($level, $user_id);
2246
}
2247
}
2248
- if(!function_exists("s2member_capability_times"))
2249
{
2250
- function s2member_capability_times($user_id = false, $levels_and_or_caps = false)
2251
{
2252
if(!$user_id) $user_id = get_current_user_id();
2253
2254
- return c_ws_plugin__s2member_registration_times::get_capability_times($user_id, $levels_and_or_caps);
2255
}
2256
}
2257
/**
2245
return c_ws_plugin__s2member_registration_times::paid_registration_time($level, $user_id);
2246
}
2247
}
2248
+ /**
2249
+ * Gets access capability times.
2250
+ *
2251
+ * @package s2Member\API_Functions
2252
+ * @since 140514
2253
+ *
2254
+ * @param integer $user_id WP User ID.
2255
+ * @param array $access_caps Optional. If not passed, this returns all times for all caps.
2256
+ * If passed, please pass an array of specific access capabilities to get the times for.
2257
+ * If removal times are desired, you should add a `-` prefix.
2258
+ * e.g. `array('ccap_music','level2','-ccap_video')`
2259
+ *
2260
+ * @return array An array of all access capability times.
2261
+ * Keys are UTC timestamps (w/ microtime precision), values are the capabilities (including `-` prefixed removals).
2262
+ * e.g. `array('1234567890.0001' => 'ccap_music', '1234567890.0002' => 'level2', '1234567890.0003' => '-ccap_video')`
2263
+ */
2264
+ if(!function_exists("s2member_access_cap_times") && !function_exists("s2member_capability_times"))
2265
{
2266
+ function s2member_access_cap_times($user_id = NULL, $access_caps = array())
2267
+ {
2268
+ if(!$user_id) $user_id = get_current_user_id();
2269
+
2270
+ return c_ws_plugin__s2member_access_cap_times::get_access_cap_times($user_id, $access_caps);
2271
+ }
2272
+ /* Deprecated in favor of `s2member_access_cap_times()`. */
2273
+ function s2member_capability_times($user_id = NULL, $access_caps = array())
2274
{
2275
if(!$user_id) $user_id = get_current_user_id();
2276
2277
+ return c_ws_plugin__s2member_access_cap_times::get_access_cap_times($user_id, $access_caps);
2278
}
2279
}
2280
/**
includes/hooks.inc.php CHANGED
@@ -94,6 +94,7 @@ add_filter("bp_core_get_site_options", "c_ws_plugin__s2member_option_forces::che
94
add_filter("random_password", "c_ws_plugin__s2member_registrations::generate_password");
95
add_action("user_register", "c_ws_plugin__s2member_registrations::configure_user_registration");
96
add_action("register_form", "c_ws_plugin__s2member_custom_reg_fields::custom_registration_fields");
97
98
add_filter("add_signup_meta", "c_ws_plugin__s2member_registrations::ms_process_signup_meta");
99
add_filter("bp_signup_usermeta", "c_ws_plugin__s2member_registrations::ms_process_signup_meta");
@@ -107,6 +108,7 @@ add_action("wpmu_activate_blog", "c_ws_plugin__s2member_registrations::configure
107
add_action("signup_extra_fields", "c_ws_plugin__s2member_custom_reg_fields::ms_custom_registration_fields");
108
109
add_action("bp_after_signup_profile_fields", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_registration_fields_4bp");
110
add_action("bp_after_profile_field_content", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_fields_4bp");
111
add_action("bp_profile_field_item", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_field_items_4bp");
112
@@ -154,14 +156,22 @@ add_action("network_admin_notices", "c_ws_plugin__s2member_admin_notices::admin_
154
add_action("pre_user_query", "c_ws_plugin__s2member_users_list::users_list_query");
155
add_filter("manage_users_columns", "c_ws_plugin__s2member_users_list::users_list_cols");
156
add_filter("manage_users_custom_column", "c_ws_plugin__s2member_users_list::users_list_display_cols", 10, 3);
157
add_action("edit_user_profile", "c_ws_plugin__s2member_users_list::users_list_edit_cols");
158
add_action("show_user_profile", "c_ws_plugin__s2member_users_list::users_list_edit_cols");
159
add_action("edit_user_profile_update", "c_ws_plugin__s2member_users_list::users_list_update_cols");
160
add_action("personal_options_update", "c_ws_plugin__s2member_users_list::users_list_update_cols");
161
add_action("set_user_role", "c_ws_plugin__s2member_registration_times::synchronize_paid_reg_times", 10, 2);
162
- add_action("update_user_meta", "c_ws_plugin__s2member_registration_times::log_capability_time", 10, 4);
163
add_filter("show_password_fields", "c_ws_plugin__s2member_user_securities::hide_password_fields", 10, 2);
164
165
add_filter("cron_schedules", "c_ws_plugin__s2member_cron_jobs::extend_cron_schedules");
166
add_action("ws_plugin__s2member_auto_eot_system__schedule", "c_ws_plugin__s2member_auto_eots::auto_eot_system");
167
94
add_filter("random_password", "c_ws_plugin__s2member_registrations::generate_password");
95
add_action("user_register", "c_ws_plugin__s2member_registrations::configure_user_registration");
96
add_action("register_form", "c_ws_plugin__s2member_custom_reg_fields::custom_registration_fields");
97
+ add_filter("registration_errors", "c_ws_plugin__s2member_registrations::custom_registration_field_errors", 10, 3);
98
99
add_filter("add_signup_meta", "c_ws_plugin__s2member_registrations::ms_process_signup_meta");
100
add_filter("bp_signup_usermeta", "c_ws_plugin__s2member_registrations::ms_process_signup_meta");
108
add_action("signup_extra_fields", "c_ws_plugin__s2member_custom_reg_fields::ms_custom_registration_fields");
109
110
add_action("bp_after_signup_profile_fields", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_registration_fields_4bp");
111
+ add_action("bp_signup_validate", "c_ws_plugin__s2member_registrations::custom_registration_field_errors_4bp");
112
add_action("bp_after_profile_field_content", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_fields_4bp");
113
add_action("bp_profile_field_item", "c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_field_items_4bp");
114
156
add_action("pre_user_query", "c_ws_plugin__s2member_users_list::users_list_query");
157
add_filter("manage_users_columns", "c_ws_plugin__s2member_users_list::users_list_cols");
158
add_filter("manage_users_custom_column", "c_ws_plugin__s2member_users_list::users_list_display_cols", 10, 3);
159
+ add_filter("manage_users_sortable_columns", "c_ws_plugin__s2member_users_list::users_list_add_sortable");
160
+ add_filter("pre_user_query", "c_ws_plugin__s2member_users_list::users_list_make_sortable");
161
add_action("edit_user_profile", "c_ws_plugin__s2member_users_list::users_list_edit_cols");
162
add_action("show_user_profile", "c_ws_plugin__s2member_users_list::users_list_edit_cols");
163
add_action("edit_user_profile_update", "c_ws_plugin__s2member_users_list::users_list_update_cols");
164
add_action("personal_options_update", "c_ws_plugin__s2member_users_list::users_list_update_cols");
165
add_action("set_user_role", "c_ws_plugin__s2member_registration_times::synchronize_paid_reg_times", 10, 2);
166
add_filter("show_password_fields", "c_ws_plugin__s2member_user_securities::hide_password_fields", 10, 2);
167
168
+ add_action("add_user_meta", "c_ws_plugin__s2member_access_cap_times::get_user_caps_before_update_on_add", 10, 3);
169
+ add_action("update_user_meta", "c_ws_plugin__s2member_access_cap_times::get_user_caps_before_update", 10, 4);
170
+
171
+ add_action("added_user_meta", "c_ws_plugin__s2member_access_cap_times::log_access_cap_times", 10, 4);
172
+ add_action("updated_user_meta", "c_ws_plugin__s2member_access_cap_times::log_access_cap_times", 10, 4);
173
+ add_action("deleted_user_meta", "c_ws_plugin__s2member_access_cap_times::log_access_cap_times_on_delete", 10, 3);
174
+
175
add_filter("cron_schedules", "c_ws_plugin__s2member_cron_jobs::extend_cron_schedules");
176
add_action("ws_plugin__s2member_auto_eot_system__schedule", "c_ws_plugin__s2member_auto_eots::auto_eot_system");
177
includes/jquery/.htaccess CHANGED
@@ -1 +1,6 @@
1
- allow from all
1
+ <IfModule authz_core_module>
2
+ Require all granted
3
+ </IfModule>
4
+ <IfModule !authz_core_module>
5
+ allow from all
6
+ </IfModule>
includes/menu-pages/menu-pages-s-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){var esc_attr=esc_html=function(str){return String(str).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");var levels='<?php echo (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; ?>';var resetUpdate=($this.hasClass("ws-plugin--s2member-reset-roles-button"))?"Reset":"Update";$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="1"){alert("s2Member's Roles/Capabilities "+((resetUpdate.toLowerCase()==="reset")?"have been successfully reset":"updated successfully")+".\nYour installation of s2Member has Membership Levels 0-"+levels+"."),$this.val(resetUpdate+" Roles/Capabilities")}else{if(response==="l"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val(resetUpdate+" Roles/Capabilities")}else{alert("Sorry, your request failed.\nAccess denied. Do you have the ability to `create_users`?"),$this.val(resetUpdate+" Roles/Capabilities")}}});return false})}if(location.href.match(/page\=ws-plugin--s2member-logs/)){$("input#ws-plugin--s2member-gateway-debug-logs-extensive-1").click(function(){var $this=$(this),thisChecked=(this.checked)?true:false;if(thisChecked){$("input#ws-plugin--s2member-gateway-debug-logs-1").attr("checked","checked")}});var $toggles=$("a.ws-plugin--s2member-log-file-viewport-toggle");$toggles.click(function(){$("textarea#ws-plugin--s2member-log-file-viewer").each(function(){var $viewer=$(this);if($viewer.attr("data-state")!=="expanded"){$viewer.css({height:($viewer.prop("scrollHeight")+50)+"px","overflow-y":"auto"});$toggles.html("&#8657; normalize viewport &#10073;");$viewer.attr("data-state","expanded")}else{$viewer.css({height:"auto","overflow-y":"scroll"});$toggles.html("&#8659; expand viewport &#8659;");$viewer.attr("data-state","scrolling")}});return false})}if(location.href.match(/page\=ws-plugin--s2member-mms-ops/)){$("select#ws-plugin--s2member-mms-registration-file").change(function(){if($(this).val()==="wp-signup"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((gv==="all")?"show":"hide")]();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((gv==="all")?((l0v>0)?l0v:"1"):"0"))}else{if($(this).val()==="wp-login"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0").hide();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");$("select#ws-plugin--s2member-mms-registration-grants").change(function(){$("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}if(location.href.match(/page\=ws-plugin--s2member-gen-ops/)){ws_plugin__s2member_generateSecurityKey=function(){var mt_rand=function(min,max){min=(arguments.length<1)?0:min;max=(arguments.length<2)?2147483647:max;return Math.floor(Math.random()*(max-min+1))+min};var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var i=0,key="";i<64;i++){key+=chars.substr(mt_rand(0,chars.length-1),1)}$("input#ws-plugin--s2member-sec-encryption-key").val(key);return false};ws_plugin__s2member_enableSecurityKey=function(){if(confirm("Edit Key? Are you sure?\nThis could break your installation!\n\n*Note* If you've been testing s2Member, feel free to change this Key before you go live. Just don't go live, and then change it. You'll have unhappy Customers. Data corruption WILL occur! For your safety, s2Member keeps a history of the last 10 Keys that you've used. If you get yourself into a real situation, s2Member will let you revert back to a previous Key.")){$("input#ws-plugin--s2member-sec-encryption-key").removeAttr("disabled")}return false};ws_plugin__s2member_securityKeyHistory=function(){$("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};$("select#ws-plugin--s2member-new-user-emails-enabled").change(function(){var $pluggable=$("input#ws-plugin--s2member-pluggables-wp-new-user-notification"),$this=$(this),$newUserEmails=$("div#ws-plugin--s2member-new-user-emails");if($pluggable.val()==="0"||$this.val()==="0"){($pluggable.val()==="0")?$this.attr("disabled","disabled"):$this.removeAttr("disabled");$(":input",$newUserEmails).attr("disabled","disabled"),$newUserEmails.css("opacity","0.5")}else{$this.removeAttr("disabled"),$(":input",$newUserEmails).removeAttr("disabled"),$newUserEmails.css("opacity","")}}).trigger("change");$("select#ws-plugin--s2member-login-reg-design-enabled").change(function(){var $this=$(this),$loginRegDesign=$("div#ws-plugin--s2member-login-reg-design");if($this.val()==="0"){$(":input",$loginRegDesign).attr("disabled","disabled"),$loginRegDesign.css("opacity","0.5"),$loginRegDesign.hide()}else{$(":input",$loginRegDesign).removeAttr("disabled"),$loginRegDesign.css("opacity",""),$loginRegDesign.show()}}).trigger("change");if($("input#ws-plugin--s2member-custom-reg-fields").length&&$("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var i,fieldDefaults,tools,table,$tools,$table;var $fields=$("input#ws-plugin--s2member-custom-reg-fields");var $configuration=$("div#ws-plugin--s2member-custom-reg-field-configuration");var fields=($fields.val())?$.JSON.parse($fields.val()):[];fields=(fields instanceof Array)?fields:[];fieldDefaults={section:"no",sectitle:"",id:"",label:"",type:"text",deflt:"",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};for(i=0;i<fields.length;i++){fields[i]=$.extend(true,{},fieldDefaults,fields[i])}tools='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>',table='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';$configuration.html(tools+table);$tools=$("div#ws-plugin--s2member-custom-reg-field-configuration-tools"),$table=$("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldSectionChange=function(select){var section=$(select).val();var sectitle_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle";(section==="yes")?$(sectitle_trs).css("display",""):$(sectitle_trs).css("display","none")};ws_plugin__s2member_customRegFieldTypeChange=function(select){var type=$(select).val();var deflt_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt",options_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options",expected_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";(type.match(/^(text|textarea)#x2F;))?$(deflt_trs).css("display",""):$(deflt_trs).css("display","none");(type.match(/^(select|selects|checkboxes|radios)#x2F;))?$(options_trs).css("display",""):$(options_trs).css("display","none");(type.match(/^(text|textarea)#x2F;))?$(expected_trs).css("display",""):$(expected_trs).css("display","none")};ws_plugin__s2member_customRegFieldDelete=function(index){var newFields=new Array();for(var i=0;i<fields.length;i++){if(i!==index){newFields.push(fields[i])}}fields=newFields,updateFields(),buildTable()};ws_plugin__s2member_customRegFieldMoveUp=function(index){if(typeof fields[index]==="object"&&typeof fields[index-1]==="object"){var prevFieldObj=fields[index-1],thisFieldObj=fields[index];fields[index-1]=thisFieldObj,fields[index]=prevFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldMoveDown=function(index){if(typeof fields[index]==="object"&&typeof fields[index+1]==="object"){var nextFieldObj=fields[index+1],thisFieldObj=fields[index];fields[index+1]=thisFieldObj,fields[index]=nextFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldCreate=function(){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field))){fields.push(field),updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(fields.length-1);alert('Field created successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldUpdate=function(index){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field,index))){fields[index]=field,updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+index;alert('Field updated successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldAdd=function(){buildTools(true)};ws_plugin__s2member_customRegFieldEdit=function(index){buildTools(false,index),scrollReset()};ws_plugin__s2member_customRegFieldCancel=function(){buildTools(),scrollReset()};var validateField=function(field,index){var editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,errors=[],options,i;if(typeof field!=="object"||typeof(field=$.extend(true,{},fieldDefaults,field))!=="object"){alert("Invalid field object. Please try again.");return false}field.sectitle=(field.section==="yes")?field.sectitle:"";field.deflt=(field.type.match(/^(text|textarea)#x2F;))?field.deflt:"";field.deflt=(field.type.match(/^(text)#x2F;))?field.deflt.replace(/[\r\n\t ]+/g," "):field.deflt;field.options=(field.type.match(/^(select|selects|checkboxes|radios)#x2F;))?field.options:"";field.expected=(field.type.match(/^(text|textarea)#x2F;))?field.expected:"";if(!field.id){errors.push("Unique Field ID:\nThis is required. Please try again.")}else{if(fieldIdExists(field.id)&&(!editing||field.id!==fields[index].id)){errors.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!field.label){errors.push("Field Label/Description:\nThis is required. Please try again.")}if(field.type.match(/^(select|selects|checkboxes|radios)#x2F;)&&!field.options){errors.push("Option Configuration File:\nThis is required. Please try again.")}else{if(field.type.match(/^(select|selects|checkboxes|radios)#x2F;)){for(i=0;i<(options=field.options.split(/[\r\n]+/)).length;i++){if(!(options[i]=$.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?#x2F;)){errors.push("Option Configuration File:\nInvalid configuration at line #"+(i+1)+".");break}}field.options=$.trim(options.join("\n"))}}if(!(field.levels=field.levels.replace(/ /g,""))){errors.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!field.levels.match(/^(all|[0-9,]+)#x2F;)){errors.push("Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n(examples: 0,1,2,3,4 or type the word: all)")}}if(field.classes&&field.classes.match(/[^a-z 0-9 _ \-]/i)){errors.push("CSS Classes:\nContains invalid characters. Please try again.\n(only: alphanumerics, underscores, hyphens, spaces)")}if(field.styles&&field.styles.match(/["\=\>\<]/)){errors.push('CSS Styles:\nContains invalid characters. Please try again.\n(do NOT use these characters: = " < >)')}if(field.attrs&&field.attrs.match(/[\>\<]/)){errors.push("Other Attributes:\nContains invalid characters. Please try again.\n(do NOT use these characters: < >)")}if(errors.length>0){alert(errors.join("\n\n"));return false}else{return field}};var updateFields=function(){$fields.val(((fields.length>0)?$.JSON.stringify(fields):""))};var fieldId2Var=function(fieldId){return(typeof fieldId==="string")?$.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var fieldTypeDesc=function(type){var types={text:"Text (single line)",textarea:"Textarea (multi-line)",select:"Select Menu (drop-down)",selects:"Select Menu (multi-option)",checkbox:"Checkbox (single)",pre_checkbox:"Checkbox (pre-checked)",checkboxes:"Checkboxes (multi-option)",radios:"Radio Buttons (multi-option)"};if(typeof types[type]==="string"){return types[type]}return""};var fieldIdExists=function(fieldId){for(var i=0;i<fields.length;i++){if(fields[i].id===fieldId){return true}}};var scrollReset=function(){scrollTo(0,$("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var buildTools=function(adding,index){var i=0,html="",form="",w=0,h=0,editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,displayForm=(adding||editing)?true:false,field=(editing)?$.extend(true,{},fieldDefaults,fields[index]):fieldDefaults;html+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),$("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(displayForm){form+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';form+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';form+="<tbody>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<select property="section" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);">';form+='<option value="no"'+((field.section==="no")?' selected="selected"':"")+'">No (this Field flows normally)</option>';form+='<option value="yes"'+((field.section==="yes")?' selected="selected"':"")+'">Yes (this Field begins a new section)</option>';form+="</select><br />";form+="<small>Optional. Allows Fields to be grouped into sections.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+">";form+='<td colspan="2">';form+="Title for this new section? (optional)<br />";form+='<input type="text" property="sectitle" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" value="'+esc_attr(field.sectitle)+'" /><br />';form+="<small>If empty, a simple divider will be used by default.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<select property="type" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);">';form+='<option value="text"'+((field.type==="text")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("text"))+"</option>";form+='<option value="textarea"'+((field.type==="textarea")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("textarea"))+"</option>";form+='<option value="select"'+((field.type==="select")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("select"))+"</option>";form+='<option value="selects"'+((field.type==="selects")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("selects"))+"</option>";form+='<option value="checkbox"'+((field.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkbox"))+"</option>";form+='<option value="pre_checkbox"'+((field.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("pre_checkbox"))+"</option>";form+='<option value="checkboxes"'+((field.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkboxes"))+"</option>";form+='<option value="radios"'+((field.type==="radios")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("radios"))+"</option>";form+="</select><br />";form+="<small>The options below may change, based on the Field Type you choose here.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<input type="text" property="label" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" value="'+esc_attr(field.label)+'" /><br />';form+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<input type="text" property="id" maxlength="25" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" value="'+esc_attr(field.id)+'" /><br />';form+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";form+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<option value="yes"'+((field.required==="yes")?' selected="selected"':"")+'">Yes (required)</option>';form+='<option value="no"'+((field.required==="no")?' selected="selected"':"")+'">No (optional)</option>';form+="</select><br />";form+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';form+="<small>* Administrators are exempt from this requirement.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="deflt" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt" rows="1">'+esc_html(field.deflt)+"</textarea><br />";form+="<small>Default value before user input is received.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)#x2F;))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * (one option per line)</label><br />';form+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="options" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options" rows="3">'+esc_html(field.options)+"</textarea><br />";form+="Here is a quick example:<br />";form+="<small>You can also specify a <em>default</em> option:</small><br />";form+="<code>US|United States|default</code><br />";form+="<code>CA|Canada</code><br />";form+="<code>VI|Virgin Islands (U.S.)</code>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)#x2F;))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';form+='<option value=""'+((field.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';form+='<option disabled="disabled"></option>';form+='<optgroup label="Specific Input Types">';form+='<option value="numeric-wp-commas"'+((field.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric (with or without decimals, commas allowed)</option>';form+='<option value="numeric"'+((field.expected==="numeric")?' selected="selected"':"")+'">Numeric (with or without decimals, no commas)</option>';form+='<option value="integer"'+((field.expected==="integer")?' selected="selected"':"")+'">Integer (whole number, without any decimals)</option>';form+='<option value="integer-gt-0"'+((field.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 (whole number, no decimals, greater than 0)</option>';form+='<option value="float"'+((field.expected==="float")?' selected="selected"':"")+'">Float (floating point number, decimals required)</option>';form+='<option value="float-gt-0"'+((field.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 (floating point number, decimals required, greater than 0)</option>';form+='<option value="date"'+((field.expected==="date")?' selected="selected"':"")+'">Date (required date format: dd/mm/yyyy)</option>';form+='<option value="email"'+((field.expected==="email")?' selected="selected"':"")+'">Email (require valid email)</option>';form+='<option value="url"'+((field.expected==="url")?' selected="selected"':"")+'">Full URL (starting with http or https)</option>';form+='<option value="domain"'+((field.expected==="domain")?' selected="selected"':"")+'">Domain Name (domain name only, without http)</option>';form+='<option value="phone"'+((field.expected==="phone")?' selected="selected"':"")+'">Phone # (10 digits w/possible hyphens,spaces,brackets)</option>';form+='<option value="uszip"'+((field.expected==="uszip")?' selected="selected"':"")+'">US Zipcode (5-9 digits w/possible hyphen)</option>';form+='<option value="cazip"'+((field.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode (6 alpha-numerics w/possible space)</option>';form+='<option value="uczip"'+((field.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode (either a US or Canadian zipcode)</option>';form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Any Character Combination">';for(i=1;i<=25;i++){form+='<option value="any-'+i+'"'+((field.expected==="any-"+i)?' selected="selected"':"")+'">Any Character Combination ( '+i+" character minimum )</option>";form+='<option value="any-'+i+'-e"'+((field.expected==="any-"+i+"-e")?' selected="selected"':"")+'">Any Character Combination ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected==="alphanumerics-spaces-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-spaces-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Spaces Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-'+i+'"'+((field.expected==="alphanumerics-spaces-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected==="alphanumerics-spaces-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-punctuation-'+i+'"'+((field.expected==="alphanumerics-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-'+i+'"'+((field.expected==="alphanumerics-"+i)?' selected="selected"':"")+'">Alphanumerics ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-'+i+'-e"'+((field.expected==="alphanumerics-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphabetics Only">';for(i=1;i<=25;i++){form+='<option value="alphabetics-'+i+'"'+((field.expected==="alphabetics-"+i)?' selected="selected"':"")+'">Alphabetics ( '+i+" character minimum )</option>";form+='<option value="alphabetics-'+i+'-e"'+((field.expected==="alphabetics-"+i+"-e")?' selected="selected"':"")+'">Alphabetics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Numeric Digits Only">';for(i=1;i<=25;i++){form+='<option value="numerics-'+i+'"'+((field.expected==="numerics-"+i)?' selected="selected"':"")+'">Numeric Digits ( '+i+" digit minimum )</option>";form+='<option value="numerics-'+i+'-e"'+((field.expected==="numerics-"+i+"-e")?' selected="selected"':"")+'">Numeric Digits ( exactly '+i+" digit"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+="</select><br />";form+="<small>Only Users/Members will be required to meet this criteria.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<input type="text" property="levels" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" value="'+esc_attr(field.levels)+'" /><br />';form+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";form+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<option value="yes"'+((field.editable==="yes")?' selected="selected"':"")+'">Yes (editable)</option>';form+='<option value="no"'+((field.editable==="no")?' selected="selected"':"")+'">No (uneditable after registration)</option>';form+='<option value="no-invisible"'+((field.editable==="no-invisible")?' selected="selected"':"")+'">No (uneditable &amp; totally invisible after registration)</option>';form+='<option value="no-always-invisible"'+((field.editable==="no-always-invisible")?' selected="selected"':"")+'">No (uneditable &amp; totally invisible, both during &amp; after registration)</option>';form+='<option value="yes-invisible"'+((field.editable==="yes-invisible")?' selected="selected"':"")+'">Yes (editable after registration / invisible during registration)</option>';form+="</select><br />";form+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<input type="text" property="classes" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" value="'+esc_attr(field.classes)+'" /><br />';form+="<small>Example: <code>my-style-1 my-style-2</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<input type="text" property="styles" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" value="'+esc_attr(field.styles)+'" /><br />';form+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<input type="text" property="attrs" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" value="'+esc_attr(field.attrs)+'" /><br />';form+='<small>Example: <code>onkeyup="" onblur=""</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';form+='<td align="left">';form+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';form+="</td>";form+='<td align="right">';form+='<input type="button" value="'+((editing)?"Update This Field":"Create Registration Field")+'" onclick="'+((editing)?"ws_plugin__s2member_customRegFieldUpdate("+index+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';form+="</td>";form+="</tr>";form+="</tbody>";form+="</table>";form+="<div>";$("body").append(form);tb_show(((editing)?"Editing Registration/Profile Field":"New Custom Registration/Profile Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form");$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}$tools.html(html)};var buildTable=function(){var l=fields.length,i=0,html="",eo="o";html+="<tbody>";html+="<tr>";html+="<th>Order</th>";html+="<th>Field Type</th>";html+="<th>Unique ID</th>";html+="<th>Required</th>";html+="<th>Levels</th>";html+="<th>- Tools -</th>";html+="</tr>";if(fields.length>0){for(i=0;i<fields.length;i++){html+='<tr class="'+esc_attr((eo=(eo==="o")?"e":"o"))+((fields[i].section==="yes")?" s":"")+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+i+'">';html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';html+='<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].id)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].required)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].levels)+"</td>";html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';html+="</tr>"}}else{html+="<tr>";html+='<td colspan="6">No Custom Fields are configured.</td>';html+="</tr>"}html+="</tbody>";$table.html(html)};buildTools(),buildTable()})()}}if(location.href.match(/page\=ws-plugin--s2member-res-ops/)){$("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's Brute Force Restriction Logs have all been reset."),$this.val("Reset Brute Force Logs")});return false});$("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's IP Restriction Logs have all been reset."),$this.val("Reset IP Restriction Logs")});return false});$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').change(function(){var thisChange=$(this).val();$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="all"&&this.checked){$this.nextAll(checkboxes).attr({checked:"checked",disabled:"disabled"})}else{if(val==="all"&&!this.checked){$this.nextAll(checkboxes).removeAttr("disabled");(thisChange==="all")?$this.nextAll(checkboxes).removeAttr("checked"):null}}})}).last().trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-down-ops/)){var updateCloudFrontPrivateKey=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyEntry=$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry");var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyEntryValue=$.trim($visiblePrivateKeyEntry.val());if((hiddenPrivateKeyValue&&!visiblePrivateKeyEntryValue)||visiblePrivateKeyEntryValue.match(/[^\r\n\u25CF]/)){$hiddenPrivateKey.val(visiblePrivateKeyEntryValue),$visiblePrivateKeyEntry.val(visiblePrivateKeyEntryValue.replace(/[^\r\n]/g,String.fromCharCode(9679)))}};$("form#ws-plugin--s2member-options-form").submit(updateCloudFrontPrivateKey);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontPrivateKey).trigger("change");var updateCloudFrontDistroCfgs=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyId=$("input#ws-plugin--s2member-amazon-cf-files-private-key-id");var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistrosStatus=$("input#ws-plugin--s2member-amazon-cf-files-distros-auto-config-status");var autoConfigDistrosStatusValue=$.trim($autoConfigDistrosStatus.val());var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyIdValue=$.trim($visiblePrivateKeyId.val());var hiddenPrivateKeyPrevConfigValue=$.trim($hiddenPrivateKey.attr("data-s-prev-config-value")),visiblePrivateKeyIdPrevConfigValue=$.trim($visiblePrivateKeyId.attr("data-s-prev-config-value"));if(autoConfigDistrosStatusValue==="configured"&&((visiblePrivateKeyIdPrevConfigValue&&visiblePrivateKeyIdValue!==visiblePrivateKeyIdPrevConfigValue)||(hiddenPrivateKeyPrevConfigValue&&hiddenPrivateKeyValue!==hiddenPrivateKeyPrevConfigValue))){alert("s2Member will need to delete and re-configure your Amazon CloudFront distributions if you change this. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}else{if(autoConfigDistrosStatusValue!=="configured"&&visiblePrivateKeyIdValue&&hiddenPrivateKeyValue){alert("s2Member will need to auto-configure your Amazon CloudFront distributions for you. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}}};$("input#ws-plugin--s2member-amazon-cf-files-private-key-id").change(updateCloudFrontDistroCfgs);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontDistroCfgs);$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames").change(function(){var $this=$(this),thisChecked=(this.checked)?true:false;var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistroCnames=$("div#ws-plugin--s2member-amazon-cf-files-auto-configure-distro-cnames");(thisChecked)?$autoConfigDistroCnames.show():$autoConfigDistroCnames.hide();(thisChecked)?$autoConfigDistros.attr("checked","checked"):null}).trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){$("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var $this=$(this),val=$this.val();var $viaCron=$("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(val==2){$viaCron.show()}else{$viaCron.hide()}})}if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){$("div.ws-menu-page select[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term#x2F;)}).change(function(){var button=this.id.replace(/^ws-plugin--s2member-(.+?)-term#x2F;g,"$1");var trialDisabled=($(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;$("p#ws-plugin--s2member-"+button+"-trial-line").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-trial-then").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-20p-rule").css("display",(trialDisabled?"none":""));(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-period").val(0):null;(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-amount").val("0.00"):null});$("div.ws-menu-page input[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps#x2F;)}).keyup(function(){var value=this.value.replace(/^(-all|-al|-a|-)[;,]*/gi,""),_all=(this.value.match(/^(-all|-al|-a|-)[;,]*/i))?"-all,":"";if(value.match(/[^a-z_0-9,]/)){this.value=_all+$.trim($.trim(value).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(button){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="",labels={};eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");var shortCode=$("input#ws-plugin--s2member-"+button+"-shortcode");var code=$("textarea#ws-plugin--s2member-"+button+"-button");var modLevel=$("select#ws-plugin--s2member-modification-level");var level=(button==="modification")?modLevel.val().split(":",2)[1]:button.replace(/^level/,"");var label=labels["level"+level].replace(/"/g,"");var desc=$.trim($("input#ws-plugin--s2member-"+button+"-desc").val().replace(/"/g,""));var trialAmount=$("input#ws-plugin--s2member-"+button+"-trial-amount").val().replace(/[^0-9\.]/g,"");var trialPeriod=$("input#ws-plugin--s2member-"+button+"-trial-period").val().replace(/[^0-9]/g,"");var trialTerm=$("select#ws-plugin--s2member-"+button+"-trial-term").val().replace(/[^A-Z]/g,"");var regAmount=$("input#ws-plugin--s2member-"+button+"-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var regRecurTimes="",regRecurRetry="1";var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-"+button+"-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-"+button+"-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();trialPeriod=(regRecur==="BN")?"0":trialPeriod;trialAmount=(!trialAmount||isNaN(trialAmount)||trialAmount<0.01||trialPeriod<=0)?"0":trialAmount;var levelCcapsPer=(regRecur==="BN"&&regTerm!=="L")?level+":"+cCaps+":"+regPeriod+" "+regTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+#x2F;g,"");if(trialAmount!=="0"&&(isNaN(trialAmount)||trialAmount<0)){alert("— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(trialAmount!=="0"&&trialAmount>10000&&currencyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00");return false}else{if(trialTerm==="D"&&trialPeriod>90){alert("— Oops, a slight problem: —\n\nMaximum Trial Days is: 90.\nIf you want to offer more than 90 days, please choose Weeks or Months from the drop-down.");return false}else{if(trialTerm==="W"&&trialPeriod>52){alert("— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.");return false}else{if(trialTerm==="M"&&trialPeriod>24){alert("— Oops, a slight problem: —\n\nMaximum Trial Months is: 24.\nIf you want to offer more than 24 months, please choose Years from the drop-down.");return false}else{if(trialTerm==="Y"&&trialPeriod>5){alert("— Oops, a slight problem: —\n\nMax Trial Period Years is: 5.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&&currencyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}}}}}}code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(trialPeriod)<=0)?code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;shortCodeTemplateAttrs+=(button==="modification")?'modify="1" ':"";shortCodeTemplateAttrs+='level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';shortCodeTemplateAttrs+=' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((button==="modification")?"1":"0")+'"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+esc_attr(regRecur)+'"'));code.html(code.val().replace(/ name\="srt" value\="(.*?)"/,' name="srt" value="'+esc_attr(regRecurTimes)+'"'));code.html(code.val().replace(/ name\="sra" value\="(.*?)"/,' name="sra" value="'+esc_attr(regRecurRetry)+'"'));code.html(code.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+esc_attr(trialAmount)+'"'));code.html(code.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+esc_attr(trialPeriod)+'"'));code.html(code.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+esc_attr(trialTerm)+'"'));code.html(code.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+esc_attr(regPeriod)+'"'));code.html(code.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+esc_attr(regTerm)+'"'));$("div#ws-plugin--s2member-"+button+"-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));(button==="modification")?alert("Your Modification Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button."):alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalCcapButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-ccap-shortcode");var code=$("textarea#ws-plugin--s2member-ccap-button");var desc=$.trim($("input#ws-plugin--s2member-ccap-desc").val().replace(/"/g,""));var regAmount=$("input#ws-plugin--s2member-ccap-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-ccap-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-ccap-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-ccap-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-ccap-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-ccap-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();var levelCcapsPer=(regRecur==="BN"&&regTerm!=="L")?"*:"+cCaps+":"+regPeriod+" "+regTerm:"*:"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+#x2F;g,"");if(!cCaps||cCaps==="-all"){alert("— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&&currencyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}shortCodeTemplateAttrs+='level="*" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-ccap-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-sp-shortcode");var code=$("textarea#ws-plugin--s2member-sp-button");var leading=$("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var regAmount=$("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var desc=$.trim($("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&&currencyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}var spIdsHours="sp:"+ids+":"+hours;shortCodeTemplateAttrs+='sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(spIdsHours)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-sp-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your WordPress Editor.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var level=$("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var subscrID=$.trim($("input#ws-plugin--s2member-reg-link-subscr-id").val());var custom=$.trim($("input#ws-plugin--s2member-reg-link-custom").val());var cCaps=$.trim($.trim($("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());var fixedTerm=$.trim($("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var $link=$("p#ws-plugin--s2member-reg-link"),$loading=$("img#ws-plugin--s2member-reg-link-loading");var levelCcapsPer=(fixedTerm&&!fixedTerm.match(/L#x2F;))?level+":"+cCaps+":"+fixedTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+#x2F;g,"");if(!subscrID){alert("— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.");return false}else{if(!custom||custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq ($_SERVER["HTTP_HOST"]); ?>')!==0){alert("— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.");return false}else{if(fixedTerm&&!fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)#x2F;)){alert("— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.");return false}}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_reg_access_link_via_ajax",ws_plugin__s2member_reg_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>',s2member_reg_access_link_subscr_gateway:"paypal",s2member_reg_access_link_subscr_id:subscrID,s2member_reg_access_link_custom:custom,s2member_reg_access_link_item_number:levelCcapsPer},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var leading=$("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var $link=$("p#ws-plugin--s2member-sp-link"),$loading=$("img#ws-plugin--s2member-sp-link-loading");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_sp_access_link_via_ajax",ws_plugin__s2member_sp_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link-via-ajax")); ?>',s2member_sp_access_link_ids:ids,s2member_sp_access_link_hours:hours},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false}}if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){$("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var $this=$(this),val=$this.val();var $rows=$("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var $prevImg=$("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(val<=0){$rows.css("display","none"),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png#x2F;,"/unchecked.png"))}else{if(val==1){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/unchecked\.png#x2F;,"/checked.png"))}else{if(val==2){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png#x2F;,"/unchecked.png"))}}}});$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').change(function(){var thisChange=$(this).val(),checkedIndexes=[];$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="removal-deletion"&&this.checked){$this.nextAll(checkboxes).slice(0,2).attr({checked:"checked",disabled:"disabled"})}else{if(val==="removal-deletion"&&!this.checked){$this.nextAll(checkboxes).slice(0,2).removeAttr("disabled");(thisChange==="removal-deletion")?$this.nextAll(checkboxes).slice(0,2).removeAttr("checked"):null}else{if(val==="modification"&&this.checked){$this.nextAll(checkboxes).slice(0,3).attr({checked:"checked",disabled:"disabled"})}else{if(val==="modification"&&!this.checked){(thisChange==="modification")?$this.nextAll(checkboxes).slice(0,3).removeAttr("checked"):null;$this.nextAll(checkboxes).slice(0,3).removeAttr("disabled")}}}}}).each(function(index){(this.checked)?checkedIndexes.push(index):null});$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").removeAttr("disabled");if($.inArray(3,checkedIndexes)===-1&&$.inArray(4,checkedIndexes)===-1&&$.inArray(5,checkedIndexes)===-1&&$.inArray(6,checkedIndexes)===-1){$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").attr("disabled","disabled")}}).last().trigger("change")}});
1
+ jQuery(document).ready(function($){var esc_attr=esc_html=function(str){return String(str).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");var levels='<?php echo (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; ?>';var resetUpdate=($this.hasClass("ws-plugin--s2member-reset-roles-button"))?"Reset":"Update";$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="1"){alert("s2Member's Roles/Capabilities "+((resetUpdate.toLowerCase()==="reset")?"have been successfully reset":"updated successfully")+".\nYour installation of s2Member has Membership Levels 0-"+levels+"."),$this.val(resetUpdate+" Roles/Capabilities")}else{if(response==="l"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val(resetUpdate+" Roles/Capabilities")}else{alert("Sorry, your request failed.\nAccess denied. Do you have the ability to `create_users`?"),$this.val(resetUpdate+" Roles/Capabilities")}}});return false})}if(locat