My Private Site - Version 2.14

Version Description

  • Force login at 'get_header' instead of 'template_redirect' Action to be compatible with wpengine.com hosting
  • Allow Custom Login page that is NOT on the current WordPress site, and clean up Settings page validation of related fields
  • Fix double display of Error Messages on Settings page
Download this release

Release Info

Developer dgewirtz
Plugin Icon 128x128 My Private Site
Version 2.14
Comparing to
See all releases

Code changes from version 2.1 to 2.14

includes/admin-settings.php CHANGED
@@ -7,6 +7,8 @@
7
  // Exit if .php file accessed directly
8
  if ( !defined( 'ABSPATH' ) ) exit;
9
 
 
 
10
  require_once( jr_ps_path() . 'includes/functions-admin.php' );
11
 
12
  add_action( 'admin_menu', 'jr_ps_admin_hook' );
@@ -21,6 +23,7 @@ add_action( 'admin_menu', 'jr_ps_admin_hook' );
21
  function jr_ps_admin_hook() {
22
  // Add Settings Page for this Plugin
23
  global $jr_ps_plugin_data;
 
24
  add_options_page( $jr_ps_plugin_data['Name'], 'Private Site', 'manage_options', 'jr_ps_settings', 'jr_ps_settings_page' );
25
  }
26
 
@@ -34,8 +37,8 @@ function jr_ps_settings_page() {
34
  global $jr_ps_plugin_data;
35
  add_thickbox();
36
  echo '<div class="wrap">';
37
- screen_icon( 'plugins' );
38
- echo '<h2>' . $jr_ps_plugin_data['Name'] . '</h2><h3>Overview</h3><p>';
39
  $settings = get_option( 'jr_ps_settings' );
40
  if ( $settings['private_site'] ) {
41
  echo 'This';
@@ -48,12 +51,25 @@ function jr_ps_settings_page() {
48
  before viewing your web site.
49
  The only things visible to anyone not logged in, including Search Engines, are:
50
  <ul>
51
- <li> &raquo; Your site's WordPress Login page;</li>
52
- <li> &raquo; Any non-WordPress components of your web site, such as HTML, PHP, ASP or other non-WordPress web page files;</li>
53
- <li> &raquo; Images and other media and text files, but only when accessed directly by their URL,
54
- or from a browser's directory view, if available.</li>
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  </ul>
56
- Other means are available to hide most, if not all, of the files mentioned above.
57
  </p>
58
  <p>
59
  To see your site, each visitor will need to be registered as a User on your WordPress site.
@@ -101,12 +117,33 @@ function jr_ps_admin_init() {
101
  'jr_ps_private_settings_section'
102
  );
103
  add_settings_section( 'jr_ps_self_registration_section',
104
- 'Allow Self-Registration',
 
105
  'jr_ps_self_registration_expl',
106
  'jr_ps_settings_page'
107
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  add_settings_field( 'reveal_registration',
109
- 'Reveal User Registration Page',
110
  'jr_ps_echo_reveal_registration',
111
  'jr_ps_settings_page',
112
  'jr_ps_self_registration_section'
@@ -128,6 +165,83 @@ function jr_ps_admin_init() {
128
  'jr_ps_settings_page',
129
  'jr_ps_landing_settings_section'
130
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
132
 
133
  /**
@@ -148,11 +262,14 @@ function jr_ps_private_settings_expl() {
148
 
149
  function jr_ps_echo_private_site() {
150
  $settings = get_option( 'jr_ps_settings' );
151
- echo '<input type="checkbox" id="private_site" name="jr_ps_settings[private_site]" value="true"';
 
 
152
  if ( $settings['private_site'] ) {
153
- echo ' checked="checked"';
 
 
154
  }
155
- echo ' />';
156
  }
157
 
158
  /**
@@ -162,24 +279,68 @@ function jr_ps_echo_private_site() {
162
  *
163
  */
164
  function jr_ps_self_registration_expl() {
165
- ?>
166
  <p>
167
- If you want Users to be able to Register themselves,
168
- please check the checkbox below
169
- or the Registration page will be blocked by this plugin
170
- when you select Private Site above.
171
- (You must also select <b>Membership</b> in <b>General Settings</b> or, for Multi-Site, <b>Allow New Registrations</b> in <b>Network Settings</b>)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  </p>
173
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
 
176
  function jr_ps_echo_reveal_registration() {
177
  $settings = get_option( 'jr_ps_settings' );
178
- echo '<input type="checkbox" id="reveal_registration" name="jr_ps_settings[reveal_registration]" value="true"';
179
- if ( $settings['reveal_registration'] ) {
180
- echo ' checked="checked"';
181
- }
182
- echo ' />';
183
  }
184
 
185
  /**
@@ -201,6 +362,9 @@ function jr_ps_landing_settings_expl() {
201
  <p>
202
  <b>Specific URL</b> only applies when <b>Go to specific URL</b> is selected.
203
  </p>
 
 
 
204
  <?php
205
  }
206
 
@@ -211,6 +375,7 @@ function jr_ps_echo_landing() {
211
  'return' => 'Return to same URL',
212
  'home' => 'Go to Site Home',
213
  'admin' => 'Go to WordPress Admin Dashboard',
 
214
  'url' => 'Go to Specific URL'
215
  ) as $val => $desc ) {
216
  if ( $first ) {
@@ -218,74 +383,415 @@ function jr_ps_echo_landing() {
218
  } else {
219
  echo '<br />';
220
  }
221
- echo '<input type="radio" id="landing" name="jr_ps_settings[landing]" ';
222
- if ( $settings['landing'] == $val ) {
223
- echo 'checked="checked"';
224
- }
225
- echo ' value="' . $val . '" /> ' . $desc;
226
  }
227
  }
228
 
229
  function jr_ps_echo_specific_url() {
230
  $settings = get_option( 'jr_ps_settings' );
231
  echo '<input type="text" id="specific_url" name="jr_ps_settings[specific_url]" size="100" maxlength="256" value="';
232
- echo esc_url( $settings['specific_url'] ) . '" />';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
 
235
  function jr_ps_validate_settings( $input ) {
236
  $valid = array();
237
  $settings = get_option( 'jr_ps_settings' );
238
 
239
- if ( array_key_exists( 'private_site', $input ) && ( $input['private_site'] === 'true' ) ) {
240
- $valid['private_site'] = TRUE;
241
- } else {
242
- $valid['private_site'] = FALSE;
 
 
 
 
 
 
243
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
- if ( array_key_exists( 'reveal_registration', $input ) && ( $input['reveal_registration'] === 'true' ) ) {
246
- $valid['reveal_registration'] = TRUE;
 
 
 
 
 
 
 
 
 
 
247
  } else {
248
- $valid['reveal_registration'] = FALSE;
 
 
 
 
 
 
 
 
 
249
  }
250
 
251
- $valid['landing'] = $input['landing'];
252
-
253
- if ( trim( $input['specific_url'] ) ) {
254
- if ( jr_ps_site_url( $input['specific_url'] ) ) {
255
- /* If URL is input without http:// or https://, then add it based on the Site URL.
256
- */
257
- $parse_url = parse_url( $input['specific_url'] );
258
- if ( is_array( $parse_url ) && array_key_exists( 'scheme', $parse_url ) && in_array( strtolower( $parse_url['scheme'] ), array( 'http', 'https' ) ) ) {
259
- $url = $input['specific_url'];
260
- } else {
261
- $parse_url = parse_url( get_home_url() );
262
- $url = $parse_url['scheme'] . '://' . $input['specific_url'];
263
- }
264
- $valid['specific_url'] = esc_url_raw( $url, array( 'http', 'https' ) );
265
- } else {
266
- /* Reset to previous URL value and generate an error message.
 
 
 
 
 
267
  */
268
- $valid['specific_url'] = $settings['specific_url'];
269
  add_settings_error(
270
  'jr_ps_settings',
271
  'jr_ps_urlerror',
272
- 'Error in URL. It must point to someplace on this WordPress web site<br /><code>'
273
- . sanitize_text_field( $input['specific_url'] ) . '</code>',
274
  'error'
275
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  }
277
  } else {
278
- $valid['specific_url'] = '';
279
- if ( 'url' === $input['landing'] ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  add_settings_error(
281
  'jr_ps_settings',
282
- 'jr_ps_nourlerror',
283
- 'Error in Landing Location: <i>Go to Specific URL</i> selected but no URL specified.',
 
284
  'error'
285
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  }
287
  }
288
 
 
 
 
 
 
 
 
 
 
 
289
  return $valid;
290
  }
291
 
7
  // Exit if .php file accessed directly
8
  if ( !defined( 'ABSPATH' ) ) exit;
9
 
10
+ DEFINE( 'JR_PS_BELOW_FIELDS', '<br /> &nbsp; ' );
11
+
12
  require_once( jr_ps_path() . 'includes/functions-admin.php' );
13
 
14
  add_action( 'admin_menu', 'jr_ps_admin_hook' );
23
  function jr_ps_admin_hook() {
24
  // Add Settings Page for this Plugin
25
  global $jr_ps_plugin_data;
26
+ $settings = get_option( 'jr_ps_settings' );
27
  add_options_page( $jr_ps_plugin_data['Name'], 'Private Site', 'manage_options', 'jr_ps_settings', 'jr_ps_settings_page' );
28
  }
29
 
37
  global $jr_ps_plugin_data;
38
  add_thickbox();
39
  echo '<div class="wrap">';
40
+ echo '<h2>' . $jr_ps_plugin_data['Name'] . '</h2>';
41
+ echo '<h3>Overview</h3><p>';
42
  $settings = get_option( 'jr_ps_settings' );
43
  if ( $settings['private_site'] ) {
44
  echo 'This';
51
  before viewing your web site.
52
  The only things visible to anyone not logged in, including Search Engines, are:
53
  <ul>
54
+ <li>
55
+ &raquo; Your site's WordPress Login page;
56
+ </li>
57
+ <li>
58
+ &raquo; Any selections in the
59
+ <b>
60
+ Visible Exclusions
61
+ </b>
62
+ section (below);
63
+ </li>
64
+ <li>
65
+ &raquo; Any non-WordPress components of your web site, such as HTML, PHP, ASP or other non-WordPress web page files;
66
+ </li>
67
+ <li>
68
+ &raquo; Images and other media and text files, but only when accessed directly by their URL,
69
+ or from a browser's directory view, if available.
70
+ </li>
71
  </ul>
72
+ Other means are available to hide most of the files mentioned above.
73
  </p>
74
  <p>
75
  To see your site, each visitor will need to be registered as a User on your WordPress site.
117
  'jr_ps_private_settings_section'
118
  );
119
  add_settings_section( 'jr_ps_self_registration_section',
120
+ '<input name="save" type="submit" value="Save Changes" class="button-primary" /><hr />'
121
+ . 'Allow Self-Registration',
122
  'jr_ps_self_registration_expl',
123
  'jr_ps_settings_page'
124
  );
125
+ if ( is_multisite() ) {
126
+ /* Clone Network Admin panels: Settings-Network Settings-Registration Settings-Allow new registrations.
127
+ It will be Read-Only except for Super Administrators.
128
+ */
129
+ add_settings_field( 'registrations',
130
+ 'Allow new registrations',
131
+ 'jr_ps_echo_registrations',
132
+ 'jr_ps_settings_page',
133
+ 'jr_ps_self_registration_section'
134
+ );
135
+ } else {
136
+ /* Clone Site Admin panels: Settings-General Settings-Membership
137
+ */
138
+ add_settings_field( 'membership',
139
+ 'Membership',
140
+ 'jr_ps_echo_membership',
141
+ 'jr_ps_settings_page',
142
+ 'jr_ps_self_registration_section'
143
+ );
144
+ }
145
  add_settings_field( 'reveal_registration',
146
+ 'Reveal Registration Page',
147
  'jr_ps_echo_reveal_registration',
148
  'jr_ps_settings_page',
149
  'jr_ps_self_registration_section'
165
  'jr_ps_settings_page',
166
  'jr_ps_landing_settings_section'
167
  );
168
+ add_settings_field( 'wplogin_php',
169
+ 'Apply to wp-login.php?',
170
+ 'jr_ps_echo_wplogin_php',
171
+ 'jr_ps_settings_page',
172
+ 'jr_ps_landing_settings_section'
173
+ );
174
+ add_settings_section( 'jr_ps_custom_login_section',
175
+ 'Custom Login',
176
+ 'jr_ps_custom_login_expl',
177
+ 'jr_ps_settings_page'
178
+ );
179
+ add_settings_field( 'custom_login',
180
+ 'Custom Login page?',
181
+ 'jr_ps_echo_custom_login',
182
+ 'jr_ps_settings_page',
183
+ 'jr_ps_custom_login_section'
184
+ );
185
+ add_settings_field( 'login_url',
186
+ 'Custom Login URL',
187
+ 'jr_ps_echo_login_url',
188
+ 'jr_ps_settings_page',
189
+ 'jr_ps_custom_login_section'
190
+ );
191
+ add_settings_field( 'custom_login_onsite',
192
+ 'Check Custom Login URL?',
193
+ 'jr_ps_echo_custom_login_onsite',
194
+ 'jr_ps_settings_page',
195
+ 'jr_ps_custom_login_section'
196
+ );
197
+ add_settings_section( 'jr_ps_exclusions_section',
198
+ 'Visible Exclusions',
199
+ 'jr_ps_exclusions_expl',
200
+ 'jr_ps_settings_page'
201
+ );
202
+ add_settings_field( 'excl_home',
203
+ 'Site Home Always Visible?<br /><code>' . get_home_url() . '</code>',
204
+ 'jr_ps_echo_excl_home',
205
+ 'jr_ps_settings_page',
206
+ 'jr_ps_exclusions_section'
207
+ );
208
+ add_settings_field( 'excl_url_add',
209
+ 'Add URL to be Always Visible',
210
+ 'jr_ps_echo_excl_url_add',
211
+ 'jr_ps_settings_page',
212
+ 'jr_ps_exclusions_section'
213
+ );
214
+ add_settings_field( 'excl_url_is_prefix',
215
+ 'Select here if URL is a Prefix',
216
+ 'jr_ps_echo_excl_url_is_prefix',
217
+ 'jr_ps_settings_page',
218
+ 'jr_ps_exclusions_section'
219
+ );
220
+ add_settings_field( 'excl_url_del',
221
+ 'Current Visible URL Entries',
222
+ 'jr_ps_echo_excl_url_del',
223
+ 'jr_ps_settings_page',
224
+ 'jr_ps_exclusions_section'
225
+ );
226
+ add_settings_section( 'jr_ps_advanced_settings_section',
227
+ 'Advanced Settings',
228
+ 'jr_ps_advanced_settings_expl',
229
+ 'jr_ps_settings_page'
230
+ );
231
+ add_settings_field( 'override_omit',
232
+ 'Allow Landing Location for Custom Login pages',
233
+ 'jr_ps_echo_override_omit',
234
+ 'jr_ps_settings_page',
235
+ 'jr_ps_advanced_settings_section'
236
+ );
237
+ if ( is_multisite() ) {
238
+ add_settings_field( 'check_role',
239
+ 'Check User Role on Site?',
240
+ 'jr_ps_echo_check_role',
241
+ 'jr_ps_settings_page',
242
+ 'jr_ps_advanced_settings_section'
243
+ );
244
+ }
245
  }
246
 
247
  /**
262
 
263
  function jr_ps_echo_private_site() {
264
  $settings = get_option( 'jr_ps_settings' );
265
+ echo '<input type="checkbox" id="private_site" name="jr_ps_settings[private_site]" value="true"'
266
+ . checked( TRUE, $settings['private_site'], FALSE ) . ' />';
267
+ echo ' (This plugin is currently ';
268
  if ( $settings['private_site'] ) {
269
+ echo 'enabled; click checkbox to disable)';
270
+ } else {
271
+ echo 'disabled; click checkbox to enable)';
272
  }
 
273
  }
274
 
275
  /**
279
  *
280
  */
281
  function jr_ps_self_registration_expl() {
282
+ echo '
283
  <p>
284
+ If you want Users to be able to Register themselves on a Private Site,
285
+ there are two Settings involved.
286
+ First
287
+ is the WordPress Setting that actually allows new Users to self-register.
288
+ It is shown here as a convenience,
289
+ but:
290
+ <ol>
291
+ <li>This is the same
292
+ ';
293
+ if ( is_multisite() ) {
294
+ echo '<b>Allow New Registrations</b> field displayed on the <b>Network Settings</b> Admin panel;</li>';
295
+ } else {
296
+ echo '<b>Membership</b> field displayed on the <b>General Settings</b> Admin panel;</li>';
297
+ }
298
+ if ( is_multisite() && !is_super_admin() ) {
299
+ echo '<li>The field is greyed out below because only Super Administrators can change this field.';
300
+ } else {
301
+ echo '<li>Clicking the Save Changes button will update its value.';
302
+ }
303
+ echo '
304
+ </li>
305
+ </ol>
306
  </p>
307
+ <p>
308
+ Second, is a Setting
309
+ (Reveal Registration Page)
310
+ for this plugin,
311
+ to make the WordPress User Registration page visible to Visitors who are not logged on.
312
+ Since Users cannot log on until they are Registered,
313
+ this Setting must be selected (check mark) for Self-Registration.
314
+ </p>
315
+ ';
316
+ }
317
+
318
+ function jr_ps_echo_registrations() {
319
+ $setting = get_site_option( 'registration' );
320
+ foreach ( array(
321
+ 'none' => 'Registration is disabled.',
322
+ 'user' => 'User accounts may be registered.',
323
+ 'blog' => 'Logged in users may register new sites.',
324
+ 'all' => 'Both sites and user accounts can be registered.'
325
+ ) as $value => $description ) {
326
+ echo '<input type="radio" id="registrations" name="jr_ps_settings[registrations]" '
327
+ . checked( $value, $setting, FALSE )
328
+ . ' value="' . $value . '" '
329
+ . disabled( is_super_admin(), FALSE, FALSE )
330
+ . ' /> ' . $description . '<br />';
331
+ }
332
+ }
333
+
334
+ function jr_ps_echo_membership() {
335
+ echo '<input type="checkbox" id="membership" name="jr_ps_settings[membership]" value="1" '
336
+ . checked( '1', get_option( 'users_can_register' ), FALSE ) . ' /> Anyone can register';
337
  }
338
 
339
  function jr_ps_echo_reveal_registration() {
340
  $settings = get_option( 'jr_ps_settings' );
341
+ echo '<input type="checkbox" id="reveal_registration" name="jr_ps_settings[reveal_registration]" value="true"'
342
+ . checked( TRUE, $settings['reveal_registration'], FALSE ) . ' />';
343
+ echo ' Do not block WordPress standard User Registration page (Advanced Setting: a check mark in this checkbox is recommended)';
 
 
344
  }
345
 
346
  /**
362
  <p>
363
  <b>Specific URL</b> only applies when <b>Go to specific URL</b> is selected.
364
  </p>
365
+ </p>
366
+ Landing Location also is applied to Logins via the Meta Widget.
367
+ <p>
368
  <?php
369
  }
370
 
375
  'return' => 'Return to same URL',
376
  'home' => 'Go to Site Home',
377
  'admin' => 'Go to WordPress Admin Dashboard',
378
+ 'omit' => 'Omit <code>?redirect_to=</code> from URL (this option is recommended for Custom Login pages)',
379
  'url' => 'Go to Specific URL'
380
  ) as $val => $desc ) {
381
  if ( $first ) {
383
  } else {
384
  echo '<br />';
385
  }
386
+ echo '<input type="radio" id="landing" name="jr_ps_settings[landing]" '
387
+ . checked( $val, $settings['landing'], FALSE )
388
+ . ' value="' . $val . '" /> ' . $desc;
 
 
389
  }
390
  }
391
 
392
  function jr_ps_echo_specific_url() {
393
  $settings = get_option( 'jr_ps_settings' );
394
  echo '<input type="text" id="specific_url" name="jr_ps_settings[specific_url]" size="100" maxlength="256" value="';
395
+ echo esc_url( $settings['specific_url'] )
396
+ . '" />'
397
+ . JR_PS_BELOW_FIELDS
398
+ . '(cut and paste URL here of Page, Post or other)'
399
+ . JR_PS_BELOW_FIELDS
400
+ . 'URL must begin with <code>'
401
+ . trim( get_home_url(), '\ /' )
402
+ . '/</code>';
403
+ }
404
+
405
+ function jr_ps_echo_wplogin_php() {
406
+ $settings = get_option( 'jr_ps_settings' );
407
+ echo '<input type="checkbox" id="wplogin_php" name="jr_ps_settings[wplogin_php]" value="true"'
408
+ . checked( TRUE, $settings['wplogin_php'], FALSE )
409
+ . ' /> Should Landing Location apply when a <code>wp-login.php</code> URL is clicked or typed without <code>&redirect_to=</code> after it?';
410
+ }
411
+
412
+ /**
413
+ * Section text for Section4
414
+ *
415
+ * Display an explanation of this Section
416
+ *
417
+ */
418
+ function jr_ps_custom_login_expl() {
419
+ echo '<p>If you have a Custom Login page at a different URL than the standard WordPress Login <code>'
420
+ . wp_login_url()
421
+ . '</code>, then you will need to specify it here. Otherwise, visitors will be redirected to the standard WordPress Login.</p>';
422
+ echo '<p>If the Custom Login page is not based on the standard WordPress Login page, it may not accept the <code>?redirect_to=http://landingurl</code> Query that is automatically added to the URL of the Custom Login page. Select Omit for "Where to after Login?" in the Landing Location section to remove the <code>redirect_to</code> Query.</p>';
423
+ echo '<p>Even with the Custom Login page selected, the standard WordPress login page will still appear in certain circumstances, such as logging into the Admin panels.<p>';
424
+ }
425
+
426
+ function jr_ps_echo_custom_login() {
427
+ $settings = get_option( 'jr_ps_settings' );
428
+ echo '<input type="checkbox" id="custom_login" name="jr_ps_settings[custom_login]" value="true" '
429
+ . checked( TRUE, $settings['custom_login'], FALSE )
430
+ . ' />';
431
+ }
432
+
433
+ function jr_ps_echo_login_url() {
434
+ $settings = get_option( 'jr_ps_settings' );
435
+ echo '<input type="text" id="login_url" name="jr_ps_settings[login_url]" size="100" maxlength="256" value="'
436
+ . esc_url( $settings['login_url'] )
437
+ . '" />'
438
+ . JR_PS_BELOW_FIELDS
439
+ . '(cut and paste Custom Login URL here; leave blank otherwise)';
440
+ }
441
+
442
+ function jr_ps_echo_custom_login_onsite() {
443
+ $settings = get_option( 'jr_ps_settings' );
444
+ echo '<input type="checkbox" id="custom_login_onsite" name="jr_ps_settings[custom_login_onsite]" value="true" '
445
+ . checked( TRUE, $settings['custom_login_onsite'], FALSE )
446
+ . ' /> '
447
+ . 'URL must begin with <code>'
448
+ . trim( get_home_url(), '\ /' )
449
+ . '/</code> (Advanced Setting: a check mark in this checkbox is recommended)';
450
+ }
451
+
452
+ /**
453
+ * Section text for Section5
454
+ *
455
+ * Display an explanation of this Section
456
+ *
457
+ */
458
+ function jr_ps_exclusions_expl() {
459
+ ?>
460
+ <p>
461
+ If you want to use your Site Home to interest visitors in registering for your site so they can see the rest of your site,
462
+ you obviously need Site Home visible to everyone.
463
+ </p><p>
464
+ You can add additional Visible site URLs,
465
+ one entry at a time,
466
+ in the
467
+ <b>
468
+ Add URL to be Always Visible
469
+ </b>
470
+ field.
471
+ </p><p>
472
+ The
473
+ <b>
474
+ Select here if URL is a Prefix
475
+ </b>
476
+ option allows you to specify a portion of a URL,
477
+ which will match, and make visible, all URLs that begin with that specified portion ("URL Prefix").
478
+ </p>
479
+ <?php
480
+ }
481
+
482
+ function jr_ps_echo_excl_home() {
483
+ $settings = get_option( 'jr_ps_settings' );
484
+ echo '<input type="checkbox" id="excl_home" name="jr_ps_settings[excl_home]" value="true"'
485
+ . checked( TRUE, $settings['excl_home'], FALSE ) . ' /> Site Home is visible to everyone?';
486
+ }
487
+
488
+ function jr_ps_echo_excl_url_add() {
489
+ echo '<input id="excl_url_add" name="jr_ps_settings[excl_url_add]" type="text" size="100" maxlength="256" value="" />'
490
+ . JR_PS_BELOW_FIELDS
491
+ . '(cut and paste URL here of Page, Post or other)'
492
+ . JR_PS_BELOW_FIELDS
493
+ . 'URL must begin with <code>'
494
+ . trim( get_home_url(), '\ /' )
495
+ . '/</code>';
496
+ }
497
+
498
+ function jr_ps_echo_excl_url_is_prefix() {
499
+ ?>
500
+ <input type="checkbox" id="excl_url_is_prefix" name="jr_ps_settings[excl_url_is_prefix]" value="true" /> Anything that begins with this URL Prefix will be Always Visible
501
+ <?php
502
+ }
503
+
504
+ function jr_ps_echo_excl_url_del() {
505
+ $settings = get_option( 'jr_ps_settings' );
506
+ if ( empty( $settings['excl_url'] ) && empty( $settings['excl_url_prefix'] ) ) {
507
+ echo 'None. To add a Visible URL Entry, fill in the fields above.<br />The Custom Login URL, if specified, is always Visible.';
508
+ } else {
509
+ $first = TRUE;
510
+ foreach ( array( 'url' => 'URL', 'url_prefix' => 'Prefix' ) as $key => $description ) {
511
+ foreach ( $settings["excl_$key"] as $index => $arr ) {
512
+ if ( $first ) {
513
+ $first = FALSE;
514
+ } else {
515
+ echo '<br />';
516
+ }
517
+ $display_url = $arr[0];
518
+ echo 'Delete <input type="checkbox" id="excl_' . $key . '_del" name="jr_ps_settings[excl_' . $key . '_del][]"'
519
+ . " value='$index' /> $description=<a href='$display_url' target='_blank'>$display_url</a>";
520
+ }
521
+ }
522
+ echo '<br />In addition, the Custom Login URL, if specified, is always Visible.';
523
+ }
524
+ }
525
+
526
+ function jr_ps_advanced_settings_expl() {
527
+ ?>
528
+ <p>
529
+ The
530
+ <b>
531
+ Allow Landing Location for Custom Login pages
532
+ </b>
533
+ setting shown immediately below will,
534
+ under some circumstances,
535
+ lock you out of your own WordPress site
536
+ and prevent Visitors from viewing your site.
537
+ You will have to rename or delete the
538
+ <code>/wp-contents/plugins/jonradio-private-site/</code>
539
+ folder with FTP or a File Manager provided with your web hosting.
540
+ If you are not familiar with either of these methods
541
+ for deleting files within your WordPress installation,
542
+ you risk making your WordPress site completely inoperative.
543
+ </p>
544
+ <?php
545
+ }
546
+
547
+ function jr_ps_echo_override_omit() {
548
+ $settings = get_option( 'jr_ps_settings' );
549
+ echo '<input type="checkbox" id="override_omit" name="jr_ps_settings[override_omit]" value="true"'
550
+ . checked( TRUE, $settings['override_omit'], FALSE ) . ' /> Can Lock You Out of Your WordPress Site! (see paragraph above)';
551
+ }
552
+
553
+ function jr_ps_echo_check_role() {
554
+ $settings = get_option( 'jr_ps_settings' );
555
+ echo '<input type="checkbox" id="check_role" name="jr_ps_settings[check_role]" value="true" '
556
+ . checked( TRUE, $settings['check_role'], FALSE )
557
+ . ' />'
558
+ . ' Only allow Users listed <a href="'
559
+ . admin_url( 'users.php' )
560
+ . '">here</a> to view this site (Security: a check mark in this checkbox is recommended)';
561
  }
562
 
563
  function jr_ps_validate_settings( $input ) {
564
  $valid = array();
565
  $settings = get_option( 'jr_ps_settings' );
566
 
567
+ foreach ( array(
568
+ 'private_site',
569
+ 'reveal_registration',
570
+ 'wplogin_php',
571
+ 'override_omit',
572
+ 'custom_login',
573
+ 'custom_login_onsite',
574
+ 'excl_home'
575
+ ) as $opt ) {
576
+ $valid[ $opt ] = isset( $input[ $opt ] ) && ( 'true' === $input[ $opt ] );
577
  }
578
+
579
+ $url = jr_v1_sanitize_url( $input['specific_url'] );
580
+ if ( '' !== $url ) {
581
+ if ( FALSE === $url ) {
582
+ /* Reset to previous URL value and generate an error message.
583
+ */
584
+ $url = $settings['specific_url'];
585
+ add_settings_error(
586
+ 'jr_ps_settings',
587
+ 'jr_ps_urlerror',
588
+ 'Landing Location URL is not a valid URL<br /><code>'
589
+ . sanitize_text_field( $input['specific_url'] ) . '</code>',
590
+ 'error'
591
+ );
592
+ } else {
593
+ if ( !jr_ps_site_url( $url ) ) {
594
+ /* Reset to previous URL value and generate an error message.
595
+ */
596
+ $url = $settings['specific_url'];
597
+ add_settings_error(
598
+ 'jr_ps_settings',
599
+ 'jr_ps_urlerror',
600
+ 'Error in Landing Location URL. It must point to someplace on this WordPress web site<br /><code>'
601
+ . sanitize_text_field( $input['specific_url'] ) . '</code>',
602
+ 'error'
603
+ );
604
+ }
605
+ }
606
+ }
607
+ $valid['specific_url'] = $url;
608
 
609
+ if ( 'url' === $input['landing'] ) {
610
+ if ( '' === $valid['specific_url'] ) {
611
+ add_settings_error(
612
+ 'jr_ps_settings',
613
+ 'jr_ps_nourlerror',
614
+ 'Error in Landing Location: <i>Go to Specific URL</i> selected but no URL specified. Set to default <i>Return to same URL</i>.',
615
+ 'error'
616
+ );
617
+ $valid['landing'] = 'return';
618
+ } else {
619
+ $valid['landing'] = 'url';
620
+ }
621
  } else {
622
+ if ( '' !== $valid['specific_url'] ) {
623
+ add_settings_error(
624
+ 'jr_ps_settings',
625
+ 'jr_ps_nourlerror',
626
+ 'Error in Landing Location: URL specified when not valid. URL deleted.',
627
+ 'error'
628
+ );
629
+ $valid['specific_url'] = '';
630
+ }
631
+ $valid['landing'] = $input['landing'];
632
  }
633
 
634
+ /* Custom Login section
635
+ */
636
+ if ( FALSE === ( $valid['login_url'] = jr_v1_sanitize_url( $input['login_url'] ) ) ) {
637
+ /* Generate an error message.
638
+ Then clear Custom Login checkbox and URL fields.
639
+ */
640
+ add_settings_error(
641
+ 'jr_ps_settings',
642
+ 'jr_ps_urlerror',
643
+ 'Custom Login URL is not a valid URL<br /><code>'
644
+ . sanitize_text_field( $input['login_url'] ) . '</code>',
645
+ 'error'
646
+ );
647
+ $valid['login_url'] = '';
648
+ $valid['custom_login'] = FALSE;
649
+ } else {
650
+ if ( ( '' !== $valid['login_url'] )
651
+ && $valid['custom_login_onsite']
652
+ && ( !jr_ps_site_url( $url ) ) ) {
653
+ /* Generate an error message.
654
+ Then clear Custom Login checkbox and URL fields.
655
  */
 
656
  add_settings_error(
657
  'jr_ps_settings',
658
  'jr_ps_urlerror',
659
+ 'Error in Custom Login URL. It must point to someplace on this WordPress web site<br /><code>'
660
+ . sanitize_text_field( $input['login_url'] ) . '</code>',
661
  'error'
662
  );
663
+ $valid['login_url'] = '';
664
+ $valid['custom_login'] = FALSE;
665
+ } else {
666
+ if ( ( '' !== $valid['login_url'] ) && ( !$valid['custom_login'] ) ) {
667
+ /* URL specified but not Custom Login checkbox
668
+
669
+ Generate an error message.
670
+ Then clear Custom Login checkbox and URL fields.
671
+ */
672
+ add_settings_error(
673
+ 'jr_ps_settings',
674
+ 'jr_ps_urlerror',
675
+ 'Error in Custom Login: URL specified but <i>Custom Login page?</i> checkbox not selected.',
676
+ 'error'
677
+ );
678
+ $valid['login_url'] = '';
679
+ $valid['custom_login'] = FALSE;
680
+ } else {
681
+ if ( ( '' === $valid['login_url'] ) && ( $valid['custom_login'] ) ) {
682
+ /* Custom Login checkbox specified but not URL
683
+
684
+ Generate an error message.
685
+ Then clear Custom Login checkbox and URL fields.
686
+ */
687
+ add_settings_error(
688
+ 'jr_ps_settings',
689
+ 'jr_ps_nourlerror',
690
+ 'Error in Custom Login: <i>Custom Login page?</i> checkbox selected but no URL specified. Checkbox deselected.',
691
+ 'error'
692
+ );
693
+ $valid['login_url'] = '';
694
+ $valid['custom_login'] = FALSE;
695
+ }
696
+ }
697
+ }
698
+ }
699
+
700
+ if ( $valid['custom_login']
701
+ && ( !$valid['override_omit'] )
702
+ && ( 'omit' !== $valid['landing'] ) ) {
703
+ $valid['landing'] = 'omit';
704
+ add_settings_error(
705
+ 'jr_ps_settings',
706
+ 'jr_ps_setomit',
707
+ 'Landing Location changed to "Omit", recommended for Custom Login pages. See Advanced Settings to Override, but please read Warnings first.',
708
+ 'updated'
709
+ );
710
+ }
711
+
712
+ if ( is_multisite() ) {
713
+ if ( is_super_admin() ) {
714
+ if ( isset( $input['registrations'] ) ) {
715
+ update_site_option( 'registration', $input['registrations'] );
716
+ }
717
+ }
718
+ /* Only in Form in WordPress Network
719
+ */
720
+ if ( isset( $input['check_role'] ) && ( $input['check_role'] === 'true' ) ) {
721
+ $valid['check_role'] = TRUE;
722
+ } else {
723
+ $valid['check_role'] = FALSE;
724
  }
725
  } else {
726
+ if ( isset( $input['membership'] ) ) {
727
+ $mem = $input['membership'];
728
+ } else {
729
+ $mem = '0';
730
+ }
731
+ update_option( 'users_can_register', $mem );
732
+ /* Not in Form except in WordPress Network
733
+ */
734
+ $valid['check_role'] = $settings['check_role'];
735
+ }
736
+
737
+ foreach ( array( 'excl_url', 'excl_url_prefix' ) as $key ) {
738
+ if ( isset( $settings[$key] ) ) {
739
+ $valid[$key] = $settings[$key];
740
+ } else {
741
+ $valid[$key] = array();
742
+ }
743
+
744
+ /* Delete URLs to Exclude from Privacy.
745
+ */
746
+ if ( isset ( $input[$key . '_del'] ) ) {
747
+ foreach ( $input[$key . '_del'] as $excl_url_del ) {
748
+ unset( $valid[$key][$excl_url_del] );
749
+ }
750
+ }
751
+ }
752
+
753
+ /* Add a URL to Exclude from Privacy.
754
+ */
755
+ $url = jr_v1_sanitize_url( $input['excl_url_add'] );
756
+ if ( '' !== $url ) {
757
+ if ( FALSE === $url ) {
758
  add_settings_error(
759
  'jr_ps_settings',
760
+ 'jr_ps_urlerror',
761
+ 'Always Visible URL is not a valid URL<br /><code>'
762
+ . sanitize_text_field( $input['excl_url_add'] ) . '</code>',
763
  'error'
764
  );
765
+ } else {
766
+ if ( jr_ps_site_url( $url ) ) {
767
+ if ( isset ( $input['excl_url_is_prefix'] ) && ( 'true' === $input['excl_url_is_prefix'] ) ) {
768
+ $key = 'excl_url_prefix';
769
+ } else {
770
+ $key = 'excl_url';
771
+ }
772
+ $valid[$key][] = array( $url, jr_v1_prep_url( $url ) );
773
+ } else {
774
+ add_settings_error(
775
+ 'jr_ps_settings',
776
+ 'jr_ps_urlerror',
777
+ 'Error in Always Visible URL. It must point to someplace on this WordPress web site<br /><code>'
778
+ . sanitize_text_field( $input['excl_url_add'] ) . '</code>',
779
+ 'error'
780
+ );
781
+ }
782
  }
783
  }
784
 
785
+ $errors = get_settings_errors();
786
+ if ( isset( $jr_ps_users_submenu ) && empty( $errors ) ) {
787
+ add_settings_error(
788
+ 'jr_ps_settings',
789
+ 'jr_ps_saved',
790
+ 'Settings Saved',
791
+ 'updated'
792
+ );
793
+ }
794
+
795
  return $valid;
796
  }
797
 
includes/common-functions.php ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* jonradio Common Functions,
3
+ intended for use in more than one jonradio plugin,
4
+ and others are encouraged to use for their own purposes.
5
+ See details below license.
6
+ */
7
+
8
+ /* Copyright 2014 jonradio (email : info@zatz.com)
9
+
10
+ This program is free software; you can redistribute it and/or modify
11
+ it under the terms of the GNU General Public License as published by
12
+ the Free Software Foundation; either version 2 of the License, or
13
+ (at your option) any later version.
14
+
15
+ This program is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ GNU General Public License for more details.
19
+
20
+ You should have received a copy of the GNU General Public License
21
+ along with this program; if not, write to the Free Software
22
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
+ */
24
+
25
+ /* Concept and Usage
26
+ Each function name is prefixed with jr_v followed by a Version Number (integer) then another underscore
27
+ then the function name.
28
+ Each function is preceded by a check for previous existence,
29
+ so that multiple plugins can use the same function without generating duplicate function definition errors.
30
+ By incorporating the Version Number into the function name, there is no danger of a plugin using the wrong version.
31
+ Standard usage is to have all these functions stored in each plugin's folder as /includes/common-functions.php
32
+ Each function has its own Version Number, which only increases when the function actually changes;
33
+ which means that common-functions.php will normally include many different version numbers in its functions;
34
+ i.e. - the version number applies independently to each function, not to the common-functions.php file as a whole.
35
+ */
36
+
37
+ // Exit if .php file accessed directly
38
+ if ( !defined( 'ABSPATH' ) ) exit;
39
+
40
+ /* As well as dealing with the low probability that a single mb_ function has been disabled in a php.ini,
41
+ this also supports older versions of PHP as mb_ functions were introduced one by one over a number of php versions.
42
+ */
43
+ if ( function_exists( 'mb_substr' ) ) {
44
+ function jr_v1_substr() {
45
+ $args = func_get_args();
46
+ if ( isset( $args[2] ) ) {
47
+ return mb_substr( $args[0], $args[1], $args[2] );
48
+ } else {
49
+ return mb_substr( $args[0], $args[1] );
50
+ }
51
+ }
52
+ } else {
53
+ function jr_v1_substr() {
54
+ $args = func_get_args();
55
+ if ( isset( $args[2] ) ) {
56
+ return substr( $args[0], $args[1], $args[2] );
57
+ } else {
58
+ return substr( $args[0], $args[1] );
59
+ }
60
+ }
61
+ }
62
+ if ( function_exists( 'mb_strlen' ) ) {
63
+ function jr_v1_strlen( $string ) {
64
+ return mb_strlen( $string );
65
+ }
66
+ } else {
67
+ function jr_v1_strlen( $string ) {
68
+ return strlen( $string );
69
+ }
70
+ }
71
+ if ( function_exists( 'mb_strtolower' ) ) {
72
+ function jr_v1_strtolower( $string ) {
73
+ return mb_strtolower( $string );
74
+ }
75
+ } else {
76
+ function jr_v1_strtolower( $string ) {
77
+ return strtolower( $string );
78
+ }
79
+ }
80
+ if ( function_exists( 'mb_stripos' ) ) {
81
+ function jr_v1_stripos( $string, $find, $offset = 0 ) {
82
+ return mb_stripos( $string, $find, $offset );
83
+ }
84
+ } else {
85
+ function jr_v1_stripos( $string, $find, $offset = 0 ) {
86
+ return stripos( $string, $find, $offset );
87
+ }
88
+ }
89
+ if ( function_exists( 'mb_strpos' ) ) {
90
+ function jr_v1_strpos( $string, $find, $offset = 0 ) {
91
+ return mb_strpos( $string, $find, $offset );
92
+ }
93
+ } else {
94
+ function jr_v1_strpos( $string, $find, $offset = 0 ) {
95
+ return strpos( $string, $find, $offset );
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Do two URLs point at the same location on a web site?
101
+ *
102
+ * Preps URL, if string
103
+ *
104
+ * @param string/array $url1 URL to compare, a string, or an array in special format created by companion function
105
+ * @param string/array $url2 URL to compare, a string, or an array in special format created by companion function
106
+ * @return bool bool TRUE if URL matches prefix; FALSE otherwise
107
+ */
108
+ if ( !function_exists( 'jr_v1_same_url' ) ) {
109
+ function jr_v1_same_url( $url1, $url2 ) {
110
+ if ( is_string( $url1 ) ) {
111
+ $url1 = jr_v1_prep_url( $url1 );
112
+ }
113
+ if ( is_string( $url2 ) ) {
114
+ $url2 = jr_v1_prep_url( $url2 );
115
+ }
116
+ return ( $url1 == $url2 );
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Does a specified Prefix URL match the given URL?
122
+ *
123
+ * Preps URL, if string
124
+ *
125
+ * @param string/array $prefix front part of a URL to compare, a string, or an array in special format created by companion function
126
+ * @param string/array $url full URL to compare, a string, or an array in special format created by companion function
127
+ * @return bool bool TRUE if Prefix matches first part of URL; FALSE otherwise
128
+ */
129
+ if ( !function_exists( 'jr_v1_same_prefix_url' ) ) {
130
+ function jr_v1_same_prefix_url( $prefix, $url ) {
131
+ if ( is_string( $prefix ) ) {
132
+ $prefix = jr_v1_prep_url( $prefix );
133
+ }
134
+ if ( is_string( $url ) ) {
135
+ $url = jr_v1_prep_url( $url );
136
+ }
137
+ if ( $url['host'] === $prefix['host'] ) {
138
+ if ( $url['path'] === $prefix['path'] ) {
139
+ /* Host and Path both exactly match for URL and Prefix specified.
140
+ */
141
+ if ( array() === $prefix['query'] ) {
142
+ $match = TRUE;
143
+ } else {
144
+ /* Now the hard part: determining a legitimate prefix match for Query
145
+ */
146
+ foreach ( $prefix['query'] as $prefix_keyword => $prefix_value ) {
147
+ $one_match = FALSE;
148
+ foreach ( $url['query'] as $url_keyword => $url_value ) {
149
+ if ( $prefix_keyword === jr_v1_substr( $url_keyword, 0, jr_v1_strlen( $prefix_keyword ) ) ) {
150
+ if ( $prefix_value === jr_v1_substr( $url_value, 0, jr_v1_strlen( $prefix_value ) ) ) {
151
+ $one_match = TRUE;
152
+ }
153
+ }
154
+ }
155
+ /* All Prefix Queries must match.
156
+ */
157
+ if ( FALSE === $one_match ) {
158
+ return FALSE;
159
+ }
160
+ }
161
+ $match = TRUE;
162
+ }
163
+ } else {
164
+ /* Paths must exactly match if Prefix specifies Query
165
+ */
166
+ if ( array() === $prefix['query'] ) {
167
+ /* No Query in Prefix, so check Path for Prefix match
168
+ */
169
+ $match = ( $prefix['path'] === jr_v1_substr( $url['path'], 0, jr_v1_strlen( $prefix['path'] ) ) );
170
+ } else {
171
+ $match = FALSE;
172
+ }
173
+ }
174
+ } else {
175
+ if ( ( '' === $prefix['path'] ) && ( array() === $prefix['query'] ) ) {
176
+ /* No Path or Query in Prefix, so check Host for Prefix match
177
+ */
178
+ $match = ( $prefix['host'] === jr_v1_substr( $url['host'], 0, jr_v1_strlen( $prefix['host'] ) ) );
179
+ } else {
180
+ /* Hosts must exactly match if Prefix specifies Path or Query
181
+ */
182
+ $match = FALSE;
183
+ }
184
+ }
185
+ return $match;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Standardize a URL into an array of values that can be accurately compared with another
191
+ *
192
+ * Preps URL, by removing any UTF Left-to-right Mark (LRM), usually found as a suffix,
193
+ * translating the URL to lower-case, removing prefix http[s]//:[www.],
194
+ * any embedded index.php and any trailing slash or #bookmark,
195
+ * and breaks up ?keyword=value queries into array elements.
196
+ *
197
+ * Structure/Elements of Array returned:
198
+ * [host] - domain.com - www. is removed, but all other subdomains are included
199
+ * [path] - /dir/file.ext
200
+ * [query] - any Queries (e.g. - "?kw=val&kw2=val2") broken up as follows:
201
+ * [$keyword] => $value with preceding equals sign, only if equals sign was present
202
+ * To simplify processing of this Array, zero length strings and empty arrays are used,
203
+ * rather than NULL entries or missing array elements.
204
+ *
205
+ * @param string $url URL to create an array from, in special format for accurate comparison
206
+ * @return array array of standardized attributes of the URL (see structure above)
207
+ */
208
+ if ( !function_exists( 'jr_v1_prep_url' ) ) {
209
+ function jr_v1_prep_url( $url ) {
210
+ /* Handle troublesome %E2%80%8E UTF Left-to-right Mark (LRM) suffix first.
211
+ */
212
+ if ( FALSE === jr_v1_stripos( $url, '%E2%80%8E' ) ) {
213
+ if ( FALSE === jr_v1_stripos( rawurlencode( $url ), '%E2%80%8E' ) ) {
214
+ $url_clean = $url;
215
+ } else {
216
+ $url_clean = rawurldecode( str_ireplace( '%E2%80%8E', '', rawurlencode( $url ) ) );
217
+ /* mb_str_ireplace() does not exist because str_ireplace() is binary-safe.
218
+ */
219
+ }
220
+ } else {
221
+ $url_clean = str_ireplace( '%E2%80%8E', '', $url );
222
+ }
223
+ $url_clean = trim( $url_clean );
224
+
225
+ /* parse_url(), especially before php Version 5.4.7,
226
+ has a history of problems when Scheme is not present,
227
+ especially for LocalHost as a Host,
228
+ so add a prefix of http:// if :// is not found
229
+ */
230
+ if ( FALSE === jr_v1_strpos( $url_clean, '://' ) ) {
231
+ $url_clean = "http://$url_clean";
232
+ }
233
+
234
+ $parse_array = parse_url( jr_v1_strtolower( $url_clean ) );
235
+ /* Get rid of URL components that do not matter to us in our comparison of URLs
236
+ */
237
+ foreach ( array( 'scheme', 'port', 'user', 'pass', 'fragment' ) as $component ) {
238
+ unset ( $parse_array[$component] );
239
+ }
240
+ /* Remove www. from host
241
+ */
242
+ if ( 'www.' === jr_v1_substr( $parse_array['host'], 0, 4 ) ) {
243
+ $parse_array['host'] = jr_v1_substr( $parse_array['host'], 4 );
244
+ }
245
+ if ( isset( $parse_array['path'] ) ) {
246
+ /* Remove any index.php occurences in path, since these can be spurious in IIS
247
+ and perhaps other environments.
248
+ */
249
+ $parse_array['path'] = str_replace( 'index.php', '', $parse_array['path'] );
250
+ /* Remove leading and trailing slashes from path
251
+ */
252
+ $parse_array['path'] = trim( $parse_array['path'], "/\\" );
253
+ } else {
254
+ $parse_array['path'] = '';
255
+ }
256
+ /* Take /?keyword=value&keyword=value URL query parameters
257
+ and break them up into array( keyword => value, keyword => value )
258
+ */
259
+ if ( isset( $parse_array['query'] ) ) {
260
+ $parms = explode( '&', $parse_array['query'] );
261
+ $parse_array['query'] = array();
262
+ foreach( $parms as $parm ) {
263
+ if ( FALSE === ( $cursor = jr_v1_strpos( $parm, '=' ) ) ) {
264
+ $parse_array['query'][$parm] = '';
265
+ } else {
266
+ /* Include the Equals Sign ("=") as the first character of the Query Value
267
+ to differentiate between a URL Prefix with a Query Keyword followed by
268
+ an Equals Sign, and one without. For example, "address" would match
269
+ address2=abc, while "address=" would not.
270
+ */
271
+ $parse_array['query'][jr_v1_substr( $parm, 0, $cursor + 1 )] = jr_v1_substr( $parm, $cursor + 1 );
272
+ }
273
+ }
274
+ } else {
275
+ $parse_array['query'] = array();
276
+ }
277
+ return $parse_array;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Sanitize a URL
283
+ *
284
+ * Preps URL, by removing any UTF Left-to-right Mark (LRM), usually found as a suffix,
285
+ * and then checks if URL is blank.
286
+ *
287
+ * @param string $url URL
288
+ * @return string/bool Sanitized URL; bool FALSE if invalid URL;
289
+ * zero length string if URL not specified
290
+ */
291
+ if ( !function_exists( 'jr_v1_sanitize_url' ) ) {
292
+ function jr_v1_sanitize_url( $url ) {
293
+ /* Handle troublesome %E2%80%8E UTF Left-to-right Mark (LRM) suffix first.
294
+ */
295
+ if ( FALSE === stripos( $url, '%E2%80%8E' ) ) {
296
+ if ( FALSE === stripos( rawurlencode( $url ), '%E2%80%8E' ) ) {
297
+ $url_clean = $url;
298
+ } else {
299
+ $url_clean = rawurldecode( str_ireplace( '%E2%80%8E', '', rawurlencode( $url ) ) );
300
+ }
301
+ } else {
302
+ $url_clean = str_ireplace( '%E2%80%8E', '', $url );
303
+ }
304
+ $url_clean = trim( $url_clean );
305
+ if ( empty( $url_clean ) ) {
306
+ return '';
307
+ }
308
+ /* Add a prefix of http:// if :// is not found
309
+ and be sure scheme is http: or https:
310
+ */
311
+ if ( FALSE === strpos( $url_clean, '://' ) ) {
312
+ if ( is_ssl()
313
+ || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] )
314
+ && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) ) {
315
+ $s = 's';
316
+ } else {
317
+ $s = '';
318
+ }
319
+ $url_clean = "http$s://$url_clean";
320
+ } else {
321
+ if ( !in_array( strtolower( parse_url( $url_clean, PHP_URL_SCHEME ) ), array( 'http', 'https' ) ) ) {
322
+ return FALSE;
323
+ }
324
+ }
325
+ return $url_clean;
326
+ }
327
+ }
328
+
329
+ ?>
includes/installed-plugins.php CHANGED
@@ -63,7 +63,7 @@ if ( function_exists( 'is_network_admin' ) && is_network_admin() ) {
63
  of the Settings admin page.
64
  */
65
  return array( 'Network Activated',
66
- '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=jr_ps_settings' . '">Settings</a>'
67
  );
68
  }
69
  } else {
@@ -82,7 +82,7 @@ if ( function_exists( 'is_network_admin' ) && is_network_admin() ) {
82
  The "page=" query string value must be equal to the slug
83
  of the Settings admin page.
84
  */
85
- array_push( $links, '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=jr_ps_settings' . '">Settings</a>' );
86
  return $links;
87
  }
88
  }
63
  of the Settings admin page.
64
  */
65
  return array( 'Network Activated',
66
+ '<a href="' . get_bloginfo('wpurl') . '/wp-admin/options-general.php?page=jr_ps_settings' . '">Settings</a>'
67
  );
68
  }
69
  } else {
82
  The "page=" query string value must be equal to the slug
83
  of the Settings admin page.
84
  */
85
+ array_push( $links, '<a href="' . get_bloginfo('wpurl') . '/wp-admin/options-general.php?page=jr_ps_settings' . '">Settings</a>' );
86
  return $links;
87
  }
88
  }
includes/public.php CHANGED
@@ -7,8 +7,51 @@
7
  // Exit if .php file accessed directly
8
  if ( !defined( 'ABSPATH' ) ) exit;
9
 
 
 
 
 
 
 
 
 
 
 
 
10
  add_action( 'login_init', 'jr_ps_login' );
11
- add_action( 'wp', 'jr_ps_force_login' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  /**
14
  * Login Detection
@@ -31,33 +74,234 @@ function jr_ps_login() {
31
  * @return NULL Nothing is returned
32
  */
33
  function jr_ps_force_login() {
34
- global $jr_ps_is_login;
35
- if ( !is_user_logged_in() && !isset( $jr_ps_is_login ) ) {
36
- $settings = get_option( 'jr_ps_settings' );
37
- switch ( $settings['landing'] ) {
38
- case 'return':
39
- // $_SERVER['HTTPS'] can be off in IIS
40
- if ( empty( $_SERVER['HTTPS'] ) || ( $_SERVER['HTTPS'] == 'off' ) ) {
41
- $http = 'http://';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  } else {
43
- $http = 'https://';
 
 
44
  }
45
- $after_login_url = $http . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
46
- break;
47
- case 'home':
48
- $after_login_url = get_home_url();
49
- break;
50
- case 'admin':
51
- $after_login_url = get_admin_url();
52
- break;
53
- case 'url':
54
- $after_login_url = trim( $settings['specific_url'] );
55
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
57
- // Avoid situations where specific URL is requested, but URL is blank
58
- if ( !empty( $after_login_url ) ) {
59
- wp_redirect( wp_login_url( $after_login_url ) );
60
- exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
  }
63
  }
7
  // Exit if .php file accessed directly
8
  if ( !defined( 'ABSPATH' ) ) exit;
9
 
10
+ /* Earliest Action Hook possible is 'template_redirect',
11
+ AFTER Rewrite: URL changed with Pretty Permalinks and
12
+ correcting the presence or absence of www. in domain name.
13
+
14
+ Unfortunately, a wpengine.com (hosting site) mandatory plugin
15
+ appears to be blocking this hook, so the next hook in time sequence
16
+ is being used:
17
+ 'get_header'
18
+ */
19
+ add_action( 'get_header', 'jr_ps_force_login' );
20
+
21
  add_action( 'login_init', 'jr_ps_login' );
22
+ add_filter( 'login_url', 'jr_ps_login_url' );
23
+ add_action( 'wp_login_failed', 'jr_ps_login_failed' );
24
+ add_action( 'wp_authenticate', 'jr_ps_wp_authenticate', 10, 2 );
25
+
26
+ $settings = get_option( 'jr_ps_settings' );
27
+ if ( $settings['wplogin_php'] ) {
28
+ /* Run this Filter "last" (Priority=100) to be sure that Paid Memberships Pro
29
+ has already runs its Filter.
30
+ */
31
+ add_filter( 'login_redirect', 'jr_ps_login_redirect_filter', 100, 3 );
32
+ /* Since it is defined when the plugin is loaded,
33
+ wait to check for the Paid Memberships Pro function.
34
+ */
35
+ add_action( 'plugins_loaded', 'jr_ps_plugins_loaded' );
36
+ function jr_ps_plugins_loaded() {
37
+ if ( function_exists( 'pmpro_login_redirect' ) ) {
38
+ add_filter( 'pmpro_login_redirect_url', 'jr_ps_pmpro_login_redirect_url_filter', 10, 3 );
39
+ function jr_ps_pmpro_login_redirect_url_filter( $redirect_to, $requested_redirect_to, $user ) {
40
+ $redirect = jr_ps_login_redirect_filter( $redirect_to, $requested_redirect_to, $user );
41
+ DEFINE( 'JR_PS_PMPRO_RUN', TRUE );
42
+ return $redirect;
43
+ }
44
+ }
45
+ }
46
+ function jr_ps_login_redirect_filter( $redirect_to, $requested_redirect_to, $user ) {
47
+ if ( !defined( 'JR_PS_PMPRO_RUN' ) ) {
48
+ if ( '' === $requested_redirect_to ) {
49
+ $redirect_to = jr_ps_after_login_url();
50
+ }
51
+ }
52
+ return $redirect_to;
53
+ }
54
+ }
55
 
56
  /**
57
  * Login Detection
74
  * @return NULL Nothing is returned
75
  */
76
  function jr_ps_force_login() {
77
+ /* return statements are performed only if User does not need to login.
78
+
79
+ First, check if User is on a Login panel.
80
+ */
81
+ global $jr_ps_is_login, $jr_ps_plugin_data;
82
+ if ( isset( $jr_ps_is_login ) ) {
83
+ return;
84
+ }
85
+
86
+ $settings = get_option( 'jr_ps_settings' );
87
+
88
+ /* Next, check if User is already logged in, and has a Role on this Site.
89
+ */
90
+ $role = TRUE;
91
+ if ( is_user_logged_in() ) {
92
+ if ( is_multisite() ) {
93
+ if ( is_user_member_of_blog() ) {
94
+ return;
95
+ } else {
96
+ /* User is logged on to a Site where he/she has no Role.
97
+ */
98
+ if ( $settings['check_role'] ) {
99
+ $role = FALSE;
100
  } else {
101
+ /* User can see all of public site.
102
+ */
103
+ return;
104
  }
105
+ }
106
+ } else {
107
+ return;
108
+ }
109
+ }
110
+
111
+ /* URL of current page without http://, i.e. - starting with domain
112
+ */
113
+ $current_url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
114
+ if ( $settings['excl_home'] && jr_v1_same_url( get_home_url(), $current_url ) ) {
115
+ return;
116
+ }
117
+ if ( $settings['custom_login'] && !empty( $settings['login_url'] ) && jr_v1_same_url( $settings['login_url'], $current_url ) ) {
118
+ return;
119
+ }
120
+ if ( isset( $settings['excl_url'] ) ) {
121
+ foreach ( $settings['excl_url'] as $arr ) {
122
+ /* Test the pre-parsed URL in the URL Exclusion list
123
+ */
124
+ if ( jr_v1_same_url( $arr[1], $current_url ) ) {
125
+ return;
126
+ }
127
+ }
128
+ }
129
+ if ( isset( $settings['excl_url_prefix'] ) ) {
130
+ foreach ( $settings['excl_url_prefix'] as $arr ) {
131
+ /* Test the pre-parsed URL in the Prefix URL Exclusion list
132
+ */
133
+ if ( jr_v1_same_prefix_url( $arr[1], $current_url ) ) {
134
+ return;
135
+ }
136
+ }
137
+ }
138
+
139
+ if ( $settings['reveal_registration'] ) {
140
+ $buddypress_path = 'buddypress/bp-loader.php';
141
+ $buddypress_active = is_plugin_active( $buddypress_path );
142
+ /* URL of Registration Page varies between Multisite (Network)
143
+ and Single Site WordPress.
144
+ Plus, wp_registration_url function was introduced in
145
+ WordPress Version 3.6.
146
+ */
147
+ if ( is_multisite() ) {
148
+ $reg_url = get_site_url( 0, 'wp-signup.php' );
149
+ $buddypress_active = $buddypress_active || is_plugin_active_for_network( $buddypress_path );
150
+ } else {
151
+ if ( function_exists( 'wp_registration_url' ) ) {
152
+ $reg_url = wp_registration_url();
153
+ } else {
154
+ $reg_url = get_site_url( 0, 'wp-login.php?action=register' );
155
+ }
156
+ }
157
+ if ( jr_v1_same_url( $reg_url, $current_url )
158
+ || ( $buddypress_active
159
+ && ( jr_v1_same_url( get_site_url( 0, 'register' ), $current_url )
160
+ || jr_v1_same_url( get_site_url( 0, 'activate' ),
161
+ parse_url( $current_url, PHP_URL_HOST )
162
+ . parse_url( $current_url, PHP_URL_PATH ) ) ) ) ) {
163
+ /* BuddyPress plugin redirects Registration URL to
164
+ either {current site}/register/ or {main site}/register/
165
+ and has its own Activation at /activate/?key=...
166
+ */
167
+ return;
168
+ }
169
+ }
170
+
171
+ /* Must exclude all of the pages generated by the Theme My Login plugin
172
+ */
173
+ $theme_my_login_path = 'theme-my-login/theme-my-login.php';
174
+ $theme_my_login_active = is_plugin_active( $theme_my_login_path );
175
+ if ( is_multisite() ) {
176
+ $theme_my_login_active = $theme_my_login_active || is_plugin_active_for_network( $theme_my_login_path );
177
+ }
178
+ if ( $theme_my_login_active ) {
179
+ if ( NULL !== ( $page = get_post( $null = NULL ) ) ) {
180
+ /* Some Versions of WordPress required that get_post() have a parameter
181
+ */
182
+ if ( ( 'page' === $page->post_type )
183
+ && in_array( $page->post_name, array( 'login', 'logout', 'lostpassword', 'register', 'resetpass' ) )
184
+ && stripos( $page->post_content, 'theme-my-login' ) ) {
185
+ return;
186
+ }
187
  }
188
+ }
189
+
190
+ /* Point of No Return:
191
+ We now know that the Visitor must be forced to login
192
+ if the Visitor wants to see the current URL.
193
+ */
194
+ if ( !$role ) {
195
+ /* User is logged on to a Site where he/she has no Role.
196
+ */
197
+ $message = 'You (User "'
198
+ . wp_get_current_user()->user_login
199
+ . '") cannot view this Site ("'
200
+ . get_bloginfo( 'name', 'display' )
201
+ . '").<hr />'
202
+ . 'Your User ID has not been defined to this Site. '
203
+ . 'If you believe that you should be able to access this Site, '
204
+ . 'please contact your network administrator or this site\'s webmaster, '
205
+ . 'and mention that your access was blocked by the <em>'
206
+ . $jr_ps_plugin_data['Name']
207
+ . '</em> plugin.';
208
+ wp_die( $message );
209
+ }
210
+
211
+ if ( $settings['custom_login'] && !empty( $settings['login_url'] ) ) {
212
+ $url = jr_ps_login_url( $settings['login_url'] );
213
+ } else {
214
+ /* wp_login_url() returns the standard WordPress login URL,
215
+ but the login_url Filter adds the ?redirect_to= query in the URL.
216
+ */
217
+ $url = wp_login_url();
218
+ }
219
+
220
+ /* wp_redirect( $url ) goes to $url right after exit on the line that follows.
221
+ */
222
+ wp_redirect( $url );
223
+ exit;
224
+ }
225
+
226
+ /**
227
+ * Add Landing Location to Login URL
228
+ *
229
+ * Although written to modify the Login URL in the Meta Widget,
230
+ * to implement Landing Location, wp_login_url() is also called
231
+ * near the end of jr_ps_force_login() above.
232
+ *
233
+ * @param string $login_url Login URL
234
+ * @param string $redirect Path to redirect to on login.
235
+ * @return string Login URL
236
+ */
237
+ function jr_ps_login_url( $login_url ) {
238
+ /* remove_query_arg() simply returns $login_url if a ?redirect_to= query is not present in the URL.
239
+ */
240
+ $url = remove_query_arg( 'redirect_to', $login_url );
241
+ /* $redirect_to is the URL passed to the standard WordPress login URL,
242
+ via the ?redirect_to= URL query parameter, to go to after login is complete.
243
+ */
244
+ $redirect_to = jr_ps_after_login_url();
245
+ /* Also avoids situations where specific URL is requested,
246
+ but URL is blank.
247
+ */
248
+ if ( !empty( $redirect_to ) ) {
249
+ $url = add_query_arg( 'redirect_to', urlencode( $redirect_to ), $url );
250
+ }
251
+ return $url;
252
+ }
253
+
254
+ function jr_ps_after_login_url() {
255
+ $settings = get_option( 'jr_ps_settings' );
256
+ switch ( $settings['landing'] ) {
257
+ case 'return':
258
+ // $_SERVER['HTTPS'] can be off in IIS
259
+ if ( empty( $_SERVER['HTTPS'] ) || ( $_SERVER['HTTPS'] == 'off' ) ) {
260
+ $http = 'http://';
261
+ } else {
262
+ $http = 'https://';
263
+ }
264
+ $after_login_url = $http . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
265
+ break;
266
+ case 'home':
267
+ $after_login_url = get_home_url();
268
+ break;
269
+ case 'admin':
270
+ $after_login_url = get_admin_url();
271
+ break;
272
+ case 'url':
273
+ $after_login_url = trim( $settings['specific_url'] );
274
+ break;
275
+ case 'omit':
276
+ $after_login_url = '';
277
+ break;
278
+ }
279
+ return $after_login_url;
280
+ }
281
+
282
+ function jr_ps_login_failed() {
283
+ $settings = get_option( 'jr_ps_settings' );
284
+ if ( $settings['custom_login'] && !empty( $settings['login_url'] ) ) {
285
+ /* wp_redirect( $url ) goes to $url right after exit on the line that follows.
286
+ */
287
+ wp_redirect( jr_ps_login_url( $settings['login_url'] ) );
288
+ exit;
289
+ } else {
290
+ return;
291
+ }
292
+ }
293
+
294
+ function jr_ps_wp_authenticate( $username, $password ) {
295
+ foreach ( array( $username, $password ) as $auth ) {
296
+ if ( empty( $auth ) ) {
297
+ jr_ps_login_failed();
298
+ } else {
299
+ /* Also catch blanks.
300
+ */
301
+ $trim_auth = rtrim( $auth );
302
+ if ( empty( $auth ) ) {
303
+ jr_ps_login_failed();
304
+ }
305
  }
306
  }
307
  }
jonradio-private-site.php CHANGED
@@ -3,13 +3,13 @@
3
  Plugin Name: jonradio Private Site
4
  Plugin URI: http://zatzlabs.com/plugins/
5
  Description: Creates a Private Site by allowing only those logged on to view the WordPress web site. Settings select the initial destination after login.
6
- Version: 2.1
7
  Author: David Gewirtz
8
  Author URI: http://zatzlabs.com/plugins/
9
  License: GPLv2
10
  */
11
 
12
- /* Copyright 2013 jonradio (email : info@zatz.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
@@ -88,22 +88,6 @@ if ( ( FALSE === ( $internal_settings = get_option( 'jr_ps_internal_settings' )
88
  $old_version = $internal_settings['version'];
89
  }
90
 
91
- $settings = get_option( 'jr_ps_settings' );
92
- if ( empty( $settings ) ) {
93
- $settings = array(
94
- 'private_site' => FALSE,
95
- 'reveal_registration' => FALSE,
96
- 'landing' => 'return',
97
- 'specific_url' => ''
98
- );
99
- /* Add if Settings don't exist, re-initialize if they were empty.
100
- */
101
- update_option( 'jr_ps_settings', $settings );
102
- /* New install on this site, old version or corrupt settings
103
- */
104
- $old_version = $jr_ps_plugin_data['Version'];
105
- }
106
-
107
  if ( version_compare( $old_version, $jr_ps_plugin_data['Version'], '!=' ) ) {
108
  /* Create, if internal settings do not exist; update if they do exist
109
  */
@@ -116,15 +100,28 @@ if ( version_compare( $old_version, $jr_ps_plugin_data['Version'], '!=' ) ) {
116
  $internal_settings['warning_privacy'] = TRUE;
117
  }
118
  update_option( 'jr_ps_internal_settings', $internal_settings );
119
-
120
- /* Handle all Settings changes made in old plugin versions
121
- */
122
- if ( version_compare( $old_version, '2.1', '<' ) ) {
123
- $settings['reveal_registration'] = FALSE;
124
- }
125
- update_option( 'jr_ps_settings', $settings );
126
  }
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  if ( is_admin() ) {
129
  require_once( jr_ps_path() . 'includes/all-admin.php' );
130
  /* Support WordPress Version 3.0.x before is_network_admin() existed
@@ -143,24 +140,96 @@ if ( is_admin() ) {
143
  // All changes to all Admin-Installed Plugins pages
144
  require_once( jr_ps_path() . 'includes/installed-plugins.php' );
145
  } else {
146
- // Public WordPress content, i.e. - not Admin pages
147
- $reveal = FALSE;
148
- if ( ( TRUE === $settings['private_site'] ) && ( TRUE === $settings['reveal_registration'] ) ) {
149
- function jr_ps_match_register( $reg_url ) {
150
- return ( 0 === strcasecmp( $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'], substr( $reg_url, 3 + strpos( $reg_url, '://' ) ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  }
152
- if ( jr_ps_match_register( wp_registration_url() ) ) {
153
- $reveal = TRUE;
154
- } else {
155
- if ( is_multisite() && jr_ps_match_register( get_site_url( 0, 'wp-signup.php' ) ) ) {
156
- $reveal = TRUE;
 
 
157
  }
158
  }
159
  }
160
- if ( FALSE === $reveal ) {
161
- // Private Site code
162
- require_once( jr_ps_path() . 'includes/public.php' );
 
163
  }
 
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  ?>
3
  Plugin Name: jonradio Private Site
4
  Plugin URI: http://zatzlabs.com/plugins/
5
  Description: Creates a Private Site by allowing only those logged on to view the WordPress web site. Settings select the initial destination after login.
6
+ Version: 2.14
7
  Author: David Gewirtz
8
  Author URI: http://zatzlabs.com/plugins/
9
  License: GPLv2
10
  */
11
 
12
+ /* Copyright 2014 jonradio (email : info@zatz.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
88
  $old_version = $internal_settings['version'];
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  if ( version_compare( $old_version, $jr_ps_plugin_data['Version'], '!=' ) ) {
92
  /* Create, if internal settings do not exist; update if they do exist
93
  */
100
  $internal_settings['warning_privacy'] = TRUE;
101
  }
102
  update_option( 'jr_ps_internal_settings', $internal_settings );
 
 
 
 
 
 
 
103
  }
104
 
105
+ require_once( jr_ps_path() . 'includes/common-functions.php' );
106
+ jr_ps_init_settings( 'jr_ps_settings',
107
+ array(
108
+ 'private_site' => FALSE,
109
+ 'reveal_registration' => TRUE,
110
+ 'landing' => 'return',
111
+ 'specific_url' => '',
112
+ 'wplogin_php' => FALSE,
113
+ 'custom_login' => FALSE,
114
+ 'login_url' => '',
115
+ 'custom_login_onsite' => TRUE,
116
+ 'excl_url' => array(),
117
+ 'excl_url_prefix' => array(),
118
+ 'excl_home' => FALSE,
119
+ 'check_role' => TRUE,
120
+ 'override_omit' => FALSE
121
+ ),
122
+ array( 'user_submenu' )
123
+ );
124
+ $settings = get_option( 'jr_ps_settings' );
125
  if ( is_admin() ) {
126
  require_once( jr_ps_path() . 'includes/all-admin.php' );
127
  /* Support WordPress Version 3.0.x before is_network_admin() existed
140
  // All changes to all Admin-Installed Plugins pages
141
  require_once( jr_ps_path() . 'includes/installed-plugins.php' );
142
  } else {
143
+ /* Public WordPress content, i.e. - not Admin pages
144
+ Do nothing if Private Site setting not set by Administrator
145
+ */
146
+ if ( $settings['private_site'] ) {
147
+ // Private Site code
148
+ require_once( jr_ps_path() . 'includes/public.php' );
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Check for missing Settings and set them to defaults
154
+ *
155
+ * Ensures that the Named Setting exists, and populates it with defaults for any missing values.
156
+ * Safe to use on every execution of a plugin because it only does an expensive Database Write
157
+ * when it finds missing Settings.
158
+ *
159
+ * @param string $name Name of Settings as looked up with get_option()
160
+ * @param array $defaults Each default Settings value in [key] => value format
161
+ * @param array $deletes Each old Settings value to delete as [0] => key format
162
+ * @return bool/Null Return value from update_option(), or NULL if update_option() not called
163
+ */
164
+ function jr_ps_init_settings( $name, $defaults, $deletes = array() ) {
165
+ $updated = FALSE;
166
+ if ( FALSE === ( $settings = get_option( $name ) ) ) {
167
+ $settings = $defaults;
168
+ $updated = TRUE;
169
+ } else {
170
+ foreach ( $defaults as $key => $value ) {
171
+ if ( !isset( $settings[$key] ) ) {
172
+ $settings[$key] = $value;
173
+ $updated = TRUE;
174
+ }
175
  }
176
+ foreach ( $deletes as $key ) {
177
+ if ( isset( $settings[$key] ) ) {
178
+ /* Don't need to check to UNSET,
179
+ but do need to know to set $updated
180
+ */
181
+ unset( $settings[$key] );
182
+ $updated = TRUE;
183
  }
184
  }
185
  }
186
+ if ( $updated ) {
187
+ $return = update_option( $name, $settings );
188
+ } else {
189
+ $return = NULL;
190
  }
191
+ return $return;
192
  }
193
 
194
+ /* Documentation of Research Done for this Plugin:
195
+ Registration URL (based on a root install in http://localhost):
196
+ WordPress 3.6.1 without jonradio Private Site installed
197
+ Single Site - not a network
198
+ http://localhost/wp-login.php?action=register
199
+ Primary Site of a Network
200
+ http://localhost/wp-signup.php
201
+ Secondary Site of a Network
202
+ http://localhost/wp-signup.php
203
+ This last URL needs a lot of thought because it means that what begins on one site ends up on another.
204
+
205
+ WordPress 3.7-beta without jonradio Private Site installed
206
+ Single Site - not a network
207
+ http://localhost/wp-login.php?action=register
208
+ Primary Site of a Network
209
+ http://localhost/wp-signup.php
210
+ Secondary Site of a Network
211
+ http://localhost/wp-signup.php
212
+
213
+ WordPress 3.0.0 without jonradio Private Site installed
214
+ Single Site - not a network
215
+ http://localhost/wp-login.php?action=register
216
+ Primary Site of a Network
217
+ http://localhost/wp-signup.php
218
+ Secondary Site of a Network
219
+ http://localhost/wp-signup.php
220
+
221
+ wp_registration_url() was not available prior to WordPress Version 3.6.0
222
+
223
+ Self-Registration allows potential Users to Register their own ID and Password without Administrator intervention or knowledge.
224
+ It is controlled by:
225
+ get_option( 'users_can_register' ) - non-Network
226
+ '1' - allows Self-Registration
227
+ '0' - no Self-Registration
228
+ get_site_option( 'registration' ) - Network (Multisite)
229
+ 'user' - allows Self-Registration
230
+ 'none' - no Self-Registration
231
+ 'blog' - Users can create new Sites in a Network
232
+ 'all' - allows Self-Registration and the creation of new Sites in a Network
233
+ */
234
+
235
  ?>
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
- === jonradio Private Site ===
2
  Contributors: dgewirtz
3
- Donate link: http://zatzlabs.com/plugins/
4
  Tags: login, visibility, private, security, plugin, pages, page, posts, post
5
  Requires at least: 3.0
6
- Tested up to: 3.6
7
- Stable tag: 2.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -12,20 +12,40 @@ Create a Private Site visible only to your registered users.
12
 
13
  == Description ==
14
 
15
- Allows the Administrator to restrict a WordPress-based web site to viewing only by registered users who are logged on.
16
 
17
- Any attempt to view any Page, Post or other part of the site will see anyone not logged on greeted by a WordPress login screen. A Settings Page allows the Administrator to determine where Users will be automatically directed to each time that they login, a "Landing Location".
18
 
19
- If you allow Self-Registration, where new Users can Register themselves, you will need to select the "Reveal User Registration Page" setting or new Users will be blocked from seeing the WordPress Registration screen.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  Another Setting allows the Private Site feature to be turned off. When the plugin is installed and activated, the Private Site feature is set off by default, to allow the Administrator an opportunity to become familiarized with the plugin's features and to set the desired settings. A warning that the site is not private appears after first activation of the plugin until the Administrator visits the plugin's Settings page.
22
 
23
  If a WordPress Network is defined, the plugin can be activated individually for select sites. Or Network Activated. In either case, each site will have its own Settings page where the Private Site feature can be turned off (default) or on for just the one site, and a Landing Location defined for each site.
24
 
25
- Login prompts are provided whenever a non-logged in user ("site visitor") attempts to access any URL controlled by WordPress on the web site. This plugin does not control non-WordPress web pages, such as .html and .php files created by hand or by other software products. Or images and other media and text files directly accessed by their URL, or from a browser's directory view, if available.
26
-
27
  Yes, there are other plugins that hide some or all WordPress content for any site visitor who is not logged on. But when I was searching for a solution for one of the web sites I support, I decided to "write my own" because I knew how it worked and felt comfortable that there would be no way for anyone not logged in to view the site, including Search Engines.
28
 
 
 
 
 
 
29
  == Installation ==
30
 
31
  This section describes how to install the *jonradio Private Site* plugin and get it working.
@@ -35,8 +55,98 @@ This section describes how to install the *jonradio Private Site* plugin and get
35
  1. Go to the plugin's Settings page to make the Site **Private**, and set where the user ends up after logging in: the **Landing Location**.
36
  1. If you allow Self-Registration, where new Users can set up their own User Name on your WordPress site or Network, you will want to select **Reveal User Registration Page** on the plugin's Settings page.
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  == Changelog ==
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  = 2.1 =
41
  * Add a settings checkbox to reveal the Register page for User Self-Registration
42
 
@@ -57,6 +167,66 @@ This section describes how to install the *jonradio Private Site* plugin and get
57
 
58
  == Upgrade Notice ==
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  = 2.1 =
61
  Allow User Self-Registration by "revealing" the Register page to those not logged in.
62
 
1
+ === My Private Site ===
2
  Contributors: dgewirtz
3
+ Donate link: http://zatzlabs.com/lab-notes/
4
  Tags: login, visibility, private, security, plugin, pages, page, posts, post
5
  Requires at least: 3.0
6
+ Tested up to: 4.3
7
+ Stable tag: 2.14
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
12
 
13
  == Description ==
14
 
15
+ *Formerly: "jonradio Private Site"*
16
 
17
+ Allows the Administrator to restrict a WordPress-based web site to viewing only by registered users who are logged on. Any attempt, by anyone not logged, to view any Page, Post or other part of the site will display a WordPress login screen.
18
 
19
+ Login prompts are provided whenever a non-logged in user ("site visitor") attempts to access any URL controlled by WordPress on the web site. This plugin does not control non-WordPress web pages, such as .html and .php files created by hand or by other software products. Or images and other media and text files directly accessed by their URL, or from a browser's directory view, if available.
20
+
21
+ Features and Settings:
22
+
23
+ * Supports WordPress Networks ("Multisite"), with Network-wide Settings planned for a future version
24
+ * Visible Exclusions settings allow the entry of a list of URLs that will always be visible, and never be hidden by the plugin; a separate Setting is provided for hiding or revealing Site Home without the need to enter its URL
25
+ * A URL Prefix option in Visible Exclusions, matches, and makes visible, all URLs that begin with the one or more partial URLs entered
26
+ * Supports Custom Login and Registration pages at URLs different than the standard WordPress Login and Registration URLs
27
+ * Landing Location settings determine what the User sees after successfully logging in
28
+ * Landing Location is set for both automatic Login prompts and the Meta Widget's Login link
29
+ * User Self-Registration settings (varies between Network and Non-Network WordPress) are presented on the plugin's Settings page for easy access
30
+ * No known Theme incompatibilities, and only known Plugin incompatibility is with the A5 Custom Login plugin
31
+ * Special functionality is included to not hide Login- and Registration-related URLs used by BuddyPress and Theme My Login plugins
32
+ * Remember Me improvements at Login via free companion plugin, jonradio Remember Me, which can be downloaded separately from the WordPress Plugin Repository
33
+ * Overrides WordPress hiding of Network Activated plugins, just for itself; tp provide this feature for all plugins, use the free companion plugin, jonradio Reveal Network Activated Plugins, which can be downloaded separately from the WordPress Plugin Repository
34
+ * Setting to disable the plugin so that other plugin Settings can be changed when the Site is not set to Private
35
+
36
+ If you allow Self-Registration, where new Users can Register themselves, you will need to select the "Reveal User Registration Page" setting or new Users will be blocked from seeing the WordPress Registration screen (on WordPress Networks, turning off the Reveal User Registration Page setting on the "Main Site" will prevent Registration from all Sites). For convenience, the WordPress Setting that controls Self-Registration of Users has been added to the Plugin's Settings page.
37
 
38
  Another Setting allows the Private Site feature to be turned off. When the plugin is installed and activated, the Private Site feature is set off by default, to allow the Administrator an opportunity to become familiarized with the plugin's features and to set the desired settings. A warning that the site is not private appears after first activation of the plugin until the Administrator visits the plugin's Settings page.
39
 
40
  If a WordPress Network is defined, the plugin can be activated individually for select sites. Or Network Activated. In either case, each site will have its own Settings page where the Private Site feature can be turned off (default) or on for just the one site, and a Landing Location defined for each site.
41
 
 
 
42
  Yes, there are other plugins that hide some or all WordPress content for any site visitor who is not logged on. But when I was searching for a solution for one of the web sites I support, I decided to "write my own" because I knew how it worked and felt comfortable that there would be no way for anyone not logged in to view the site, including Search Engines.
43
 
44
+ > <strong>Adoption Notice</strong><br>
45
+ > This plugin was recently adopted by David Gewirtz and ongoing support and updates will continue. Feel free to visit [David's Lab Notes](http://zatzlabs.com/lab-notes/) for additional details and to sign up for emailed news updates.
46
+
47
+ Special thanks to Jon 'jonradio' Pearkins for creating the plugin and making adoption possible.
48
+
49
  == Installation ==
50
 
51
  This section describes how to install the *jonradio Private Site* plugin and get it working.
55
  1. Go to the plugin's Settings page to make the Site **Private**, and set where the user ends up after logging in: the **Landing Location**.
56
  1. If you allow Self-Registration, where new Users can set up their own User Name on your WordPress site or Network, you will want to select **Reveal User Registration Page** on the plugin's Settings page.
57
 
58
+ == Frequently Asked Questions ==
59
+
60
+ = How do I fix Redirect Loops (browser cycles for a long time then gives up)? =
61
+
62
+ By far, the most common way to create a Redirect Loop on your browser with this *jonradio Private Site* plugin is to specify both Custom Login page and Landing Location on the plugin's Settings page. Simply setting "Where to after Login?" in the Landing Location section to "Omit ?redirect_to= from URL" should correct the problem.
63
+
64
+ This problem has been observed when the URL of the Custom Login page is a WordPress Page. It occurs because, for Page URLs, WordPress uses the ?redirect_to= Query keyword for purposes other than a Landing Location.
65
+
66
+ = What happened? I changed my Permalinks and now some things don't work. =
67
+
68
+ Whenever you change your WordPress Permalinks (Settings-Permalinks in Admin panels), this *jonradio Private Site* plugin does **not** automatically change any URLs you have entered in the plugin's Settings. You will therefore want to make changes to URLs in the plugin's Settings whenever you change Permalinks.
69
+
70
+ = Why has the plugin's Settings entry disappeared from the WordPress Admin Users submenu? =
71
+
72
+ At user request, to reduce clutter.
73
+
74
  == Changelog ==
75
 
76
+ = 2.14 =
77
+ * Force login at 'get_header' instead of 'template_redirect' Action to be compatible with wpengine.com hosting
78
+ * Allow Custom Login page that is NOT on the current WordPress site, and clean up Settings page validation of related fields
79
+ * Fix double display of Error Messages on Settings page
80
+
81
+ = 2.13 =
82
+ * Remove Plugin's entry on Users submenu on WordPress Admin panels
83
+ * Remove associated Setting, which determined whether Users submenu entry existed
84
+
85
+ = 2.12 =
86
+ * Wait until Pretty Permalinks applied before deciding whether to force a login
87
+ * Add an Override Advanced Setting with Warnings on Usage, to allow Landing Location and Custom Login to both be specified.
88
+ * Correct coding error that allowed Landing Location with Custom Login, a potential Redirection error
89
+ * Fix Error Log warning on [mb]strpos Offset parameter
90
+
91
+ = 2.11.4 =
92
+ * Use Custom Login setting, if present, to redirect failed login attempts with blank username and/or password
93
+
94
+ = 2.11.3 =
95
+ * Use Custom Login setting, if present, to redirect failed login attempts
96
+
97
+ = 2.11.2 =
98
+ * Provide a Setting to disable User with No Role behaviour introduced in 2.11
99
+
100
+ = 2.11.1 =
101
+ * Remove forced logout when User with No Role attempts to access a Site (Network/Multisite install), to fix repeated messages when wp_logout is hooked by other plugins
102
+
103
+ = 2.11 =
104
+ * In a WordPress Network ("Multisite"), block Users with No Role on the current Site
105
+ * Make Landing Location work when free Paid Membership Pro plugin is activated
106
+
107
+ = 2.10.1 =
108
+ * Add setting to obey Landing Location for users who login via a URL of wp-login.php without a &redirect_to= following
109
+
110
+ = 2.10 =
111
+ * Add setting to not display a Users submenu option for the plugin's settings
112
+ * Conditional logic for Settings Saved update message in Validate function
113
+
114
+ = 2.9 =
115
+ * Set Landing Location for logins via Meta Widget link, as well as automatic Login prompts
116
+
117
+ = 2.8 =
118
+ * Add Prefix option to Always Visible URLs
119
+ * Automatically use mb_ Multi-Byte string functions, if available
120
+
121
+ = 2.7 =
122
+ * Add Custom Login URL setting
123
+
124
+ = 2.6.1 =
125
+ * Older versions of WordPress require a parameter be passed to get_post()
126
+
127
+ = 2.6 =
128
+ * Detect and make visible Login-associated Pages created by the Theme My Login plugin
129
+
130
+ = 2.5 =
131
+ * Allow other URLs to be Always Visible with new Setting
132
+
133
+ = 2.4.2 =
134
+ * Reveal BuddyPress /activate/ Activation page when Reveal Registration selected
135
+
136
+ = 2.4.1 =
137
+ * Fix bug in URL matching for Root, where one URL has a trailing slash and the other does not
138
+
139
+ = 2.4 =
140
+ * Handle BuddyPress' redirection of Register URL in Reveal Registration
141
+
142
+ = 2.3 =
143
+ * Add Setting to Reveal Home Page on a Private Site
144
+ * Fixed Problems with wp_registration_url function in WordPress prior to Version 3.6
145
+
146
+ = 2.2 =
147
+ * Add the WordPress User Self-Registration field to the plugin's Settings page
148
+ * Add the Settings page to the User submenu of Admin panel, too
149
+
150
  = 2.1 =
151
  * Add a settings checkbox to reveal the Register page for User Self-Registration
152
 
167
 
168
  == Upgrade Notice ==
169
 
170
+ = 2.14 =
171
+ Support wpengine.com hosting and off-site Login pages
172
+
173
+ = 2.13 =
174
+ Reduce WordPress Admin panels Menu clutter by removing plugin Settings from Users submenu
175
+
176
+ = 2.12 =
177
+ Correct handling of www. in a URL by waiting until Pretty Permalinks applied before deciding whether to force Login
178
+
179
+ = 2.11.3 =
180
+ Correct Failed Logins when Custom Login selected
181
+
182
+ = 2.11.2 =
183
+ Add Setting to control User with No Role
184
+
185
+ = 2.11.1 =
186
+ Fix User with No Role errors on Network/Multisite
187
+
188
+ = 2.11 =
189
+ Improves Multisite security and supports Paid Membership Pro
190
+
191
+ = 2.10.1 =
192
+ Landing Location obeyed for direct access with wp-login.php URL
193
+
194
+ = 2.10 =
195
+ Allow deletion of Users submenu entry for plugin settings
196
+
197
+ = 2.9 =
198
+ Meta Widget logins now go to Landing Location
199
+
200
+ = 2.8 =
201
+ Support Prefix URL for Always Visible pages
202
+
203
+ = 2.7 =
204
+ Support Custom Login page
205
+
206
+ = 2.6.1 =
207
+ Support Theme My Login plugin with older versions of WordPress
208
+
209
+ = 2.6 =
210
+ Support Theme My Login plugin
211
+
212
+ = 2.5 =
213
+ Allow many Always Visible pages
214
+
215
+ = 2.4.2 =
216
+ Reveal BuddyPress Activation page
217
+
218
+ = 2.4.1 =
219
+ Home Page better URL matching for Root Home Pages
220
+
221
+ = 2.4 =
222
+ Support BuddyPress
223
+
224
+ = 2.3 =
225
+ New Setting to display Home Page on a Private Site.
226
+
227
+ = 2.2 =
228
+ Display WordPress Self-Registration field on plugin Settings page.
229
+
230
  = 2.1 =
231
  Allow User Self-Registration by "revealing" the Register page to those not logged in.
232