Move Login - Version 2.4.2

Version Description

  • 2017/02/04
  • Fixed a simple PHP warning.
Download this release

Release Info

Developer GregLone
Plugin Icon 128x128 Move Login
Version 2.4.2
Comparing to
See all releases

Code changes from version 2.3 to 2.4.2

inc/activate.php CHANGED
@@ -7,104 +7,119 @@ if ( ! defined( 'ABSPATH' ) ) {
7
  /* !ACTIVATION ================================================================================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
- // Trigger wp_die() on plugin activation if the server configuration does not fit. Or, set a transient for admin notices.
11
-
 
 
12
  function sfml_activate() {
13
  global $is_apache, $is_iis7;
14
 
15
- if ( ! function_exists( 'sfml_write_rules' ) ) {
16
- include( SFML_PLUGIN_DIR . 'inc/rewrite.php' );
17
- }
18
-
19
  $is_nginx = sfml_is_nginx();
20
  $dies = array();
21
 
22
- // The plugin needs the request uri
23
  if ( empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) && empty( $_SERVER['REQUEST_URI'] ) ) {
24
  $dies[] = 'error_no_request_uri';
25
  }
26
 
27
- // IIS7
28
- if ( $is_iis7 && ! iis7_supports_permalinks() ) {
29
- $dies[] = 'error_no_mod_rewrite';
 
 
 
 
30
  }
31
- // Apache
32
- elseif ( $is_apache && ! got_mod_rewrite() ) {
33
- $dies[] = 'error_no_mod_rewrite';
 
 
 
 
34
  }
35
- // None
36
  elseif ( ! $is_iis7 && ! $is_apache && ! $is_nginx ) {
37
  $dies[] = 'error_unknown_server_conf';
38
  }
39
 
40
- // die()s: don't activate the plugin.
41
- if ( ! empty( $dies ) ) {
42
-
43
- // i18n early loading.
44
  sfml_lang_init();
45
 
46
  $dies = array_filter( array_map( 'sfml_notice_message', $dies ) );
47
  $dies = __( '<strong>Move Login</strong> has not been activated.', 'sf-move-login' ) . '<br/>' . implode( '<br/>', $dies );
48
 
49
- wp_die( $dies, __( 'Error' ), array( 'back_link' => true ) );
50
-
51
  }
52
 
53
- // Perhaps we'll need to display some notices. Add the rewrite rules to the .htaccess/web.config file.
54
- set_transient( 'sfml_notices-' . get_current_user_id(), '1' ); // 1 means "Update the file".
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
- register_activation_hook( SFML_FILE, 'sfml_activate' );
58
-
59
 
60
  /*------------------------------------------------------------------------------------------------*/
61
  /* !DEACTIVATION ================================================================================ */
62
  /*------------------------------------------------------------------------------------------------*/
63
 
64
- // !Remove rewrite rules from the .htaccess/web.config file.
65
-
 
 
66
  function sfml_deactivate() {
67
- global $is_apache, $is_iis7;
68
 
69
- if ( ! function_exists( 'sfml_write_rules' ) ) {
70
- include( SFML_PLUGIN_DIR . 'inc/rewrite.php' );
71
- }
72
 
73
- // IIS
74
- if ( $is_iis7 ) {
75
- sfml_insert_iis7_rewrite_rules( 'SF Move Login' ); // Empty content
76
- }
77
- // Apache
78
- elseif ( $is_apache ) {
79
- sfml_insert_apache_rewrite_rules( 'SF Move Login' ); // Empty content
80
- }
81
  }
82
 
83
- register_deactivation_hook( SFML_FILE, 'sfml_deactivate' );
84
-
85
 
86
  /*------------------------------------------------------------------------------------------------*/
87
  /* !UTILITIES =================================================================================== */
88
  /*------------------------------------------------------------------------------------------------*/
89
 
90
- // !Messages used for notices and die()s
91
-
92
- function sfml_notice_message( $k ) {
 
 
 
 
 
93
  global $is_iis7;
94
  static $messages;
95
 
96
- if ( is_null( $messages ) ) {
97
  $file = $is_iis7 ? '<code>web.config</code>' : '<code>.htaccess</code>';
98
- $link = '<a href="' . ( is_multisite() ? network_admin_url( 'settings.php?page=move-login' ) : admin_url( 'options-general.php?page=move-login' ) ) . '">Move Login</a>';
99
 
100
  $messages = array(
101
  'error_no_request_uri' => __( 'It seems your server configuration prevent the plugin to work properly. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
102
  'error_no_mod_rewrite' => __( 'It seems the url rewrite module is not activated on your server. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
103
  'error_unknown_server_conf' => __( 'It seems your server does not use <i>Apache</i>, <i>Nginx</i>, nor <i>IIS7</i>. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
 
104
  'error_file_not_writable' => sprintf( __( '<strong>Move Login</strong> needs access to the %1$s file. Please visit the %2$s settings page and copy/paste the given code into the %1$s file.', 'sf-move-login' ), $file, $link ),
 
105
  'updated_is_nginx' => sprintf( __( 'It seems your server uses a <i>Nginx</i> system. You have to edit the rewrite rules by yourself in the configuration file. Please visit the %s settings page and take a look at the rewrite rules. <strong>Move Login</strong> is running but won\'t work correctly until you deal with those rewrite rules.', 'sf-move-login' ), $link ),
106
  );
107
  }
108
 
109
- return isset( $messages[ $k ] ) ? $messages[ $k ] : '';
110
  }
7
  /* !ACTIVATION ================================================================================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
+ register_activation_hook( SFML_FILE, 'sfml_activate' );
11
+ /**
12
+ * Trigger `wp_die()` on plugin activation if the server configuration does not fit. Or, set a transient for admin notices.
13
+ */
14
  function sfml_activate() {
15
  global $is_apache, $is_iis7;
16
 
 
 
 
 
17
  $is_nginx = sfml_is_nginx();
18
  $dies = array();
19
 
20
+ // The plugin needs the request URI.
21
  if ( empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) && empty( $_SERVER['REQUEST_URI'] ) ) {
22
  $dies[] = 'error_no_request_uri';
23
  }
24
 
25
+ // Apache.
26
+ if ( $is_apache ) {
27
+ require_once( ABSPATH . WPINC . '/functions.php' );
28
+
29
+ if ( ! got_mod_rewrite() ) {
30
+ $dies[] = 'error_no_mod_rewrite';
31
+ }
32
  }
33
+ // IIS7.
34
+ elseif ( $is_iis7 ) {
35
+ require_once( ABSPATH . 'wp-admin/includes/misc.php' );
36
+
37
+ if ( ! iis7_supports_permalinks() ) {
38
+ $dies[] = 'error_no_mod_rewrite';
39
+ }
40
  }
41
+ // None.
42
  elseif ( ! $is_iis7 && ! $is_apache && ! $is_nginx ) {
43
  $dies[] = 'error_unknown_server_conf';
44
  }
45
 
46
+ // `die()`s: don't activate the plugin.
47
+ if ( $dies ) {
48
+ // I18n early loading.
 
49
  sfml_lang_init();
50
 
51
  $dies = array_filter( array_map( 'sfml_notice_message', $dies ) );
52
  $dies = __( '<strong>Move Login</strong> has not been activated.', 'sf-move-login' ) . '<br/>' . implode( '<br/>', $dies );
53
 
54
+ wp_die( $dies, __( 'Error', 'sf-move-login' ), array( 'back_link' => true ) );
 
55
  }
56
 
57
+ /**
58
+ * Perhaps we'll need to display some notices. Add the rewrite rules to the .htaccess/web.config file.
59
+ * 1 means "Update the file".
60
+ */
61
+ set_transient( 'sfml_activation-' . get_current_user_id(), '1' );
62
+
63
+ /**
64
+ * Triggered when Move Login is activated.
65
+ *
66
+ * @since 2.4
67
+ */
68
+ do_action( 'sfml_activate' );
69
  }
70
 
 
 
71
 
72
  /*------------------------------------------------------------------------------------------------*/
73
  /* !DEACTIVATION ================================================================================ */
74
  /*------------------------------------------------------------------------------------------------*/
75
 
76
+ register_deactivation_hook( SFML_FILE, 'sfml_deactivate' );
77
+ /**
78
+ * Remove rewrite rules from the `.htaccess`/`web.config` file on deactivation.
79
+ */
80
  function sfml_deactivate() {
81
+ sfml_include_rewrite_file();
82
 
83
+ sfml_write_rules( array() );
 
 
84
 
85
+ /**
86
+ * Triggered when Move Login is deactivated.
87
+ *
88
+ * @since 2.4
89
+ */
90
+ do_action( 'sfml_deactivate' );
 
 
91
  }
92
 
 
 
93
 
94
  /*------------------------------------------------------------------------------------------------*/
95
  /* !UTILITIES =================================================================================== */
96
  /*------------------------------------------------------------------------------------------------*/
97
 
98
+ /**
99
+ * Messages used for notices and `die()`s.
100
+ *
101
+ * @param (string) $message_id A message ID.
102
+ *
103
+ * @return (string|array) A message if `$message_id` is a valid ID. An array otherwize.
104
+ */
105
+ function sfml_notice_message( $message_id ) {
106
  global $is_iis7;
107
  static $messages;
108
 
109
+ if ( ! isset( $messages ) ) {
110
  $file = $is_iis7 ? '<code>web.config</code>' : '<code>.htaccess</code>';
111
+ $link = '<a href="' . esc_url( is_multisite() ? network_admin_url( 'settings.php?page=move-login' ) : admin_url( 'options-general.php?page=move-login' ) ) . '">Move Login</a>';
112
 
113
  $messages = array(
114
  'error_no_request_uri' => __( 'It seems your server configuration prevent the plugin to work properly. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
115
  'error_no_mod_rewrite' => __( 'It seems the url rewrite module is not activated on your server. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
116
  'error_unknown_server_conf' => __( 'It seems your server does not use <i>Apache</i>, <i>Nginx</i>, nor <i>IIS7</i>. <strong>Move Login</strong> won\'t work.', 'sf-move-login' ),
117
+ /** Translators: 1 is a file name, 2 is a "Move Login" link. */
118
  'error_file_not_writable' => sprintf( __( '<strong>Move Login</strong> needs access to the %1$s file. Please visit the %2$s settings page and copy/paste the given code into the %1$s file.', 'sf-move-login' ), $file, $link ),
119
+ /** Translators: %s is a "Move Login" link. */
120
  'updated_is_nginx' => sprintf( __( 'It seems your server uses a <i>Nginx</i> system. You have to edit the rewrite rules by yourself in the configuration file. Please visit the %s settings page and take a look at the rewrite rules. <strong>Move Login</strong> is running but won\'t work correctly until you deal with those rewrite rules.', 'sf-move-login' ), $link ),
121
  );
122
  }
123
 
124
+ return isset( $messages[ $message_id ] ) ? $messages[ $message_id ] : '';
125
  }
inc/admin.php CHANGED
@@ -3,108 +3,71 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  die( 'Cheatin\' uh?' );
4
  }
5
 
6
- /*------------------------------------------------------------------------------------------------*/
7
- /* !UTILITIES =================================================================================== */
8
- /*------------------------------------------------------------------------------------------------*/
9
-
10
- if ( ! function_exists( 'get_main_blog_id' ) ) :
11
- function get_main_blog_id() {
12
- static $blog_id;
13
-
14
- if ( ! isset( $blog_id ) ) {
15
- if ( ! is_multisite() ) {
16
- $blog_id = 1;
17
- } elseif ( ! empty( $GLOBALS['current_site']->blog_id ) ) {
18
- $blog_id = absint( $GLOBALS['current_site']->blog_id );
19
- } elseif ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
20
- $blog_id = absint( BLOG_ID_CURRENT_SITE );
21
- } elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) {
22
- // deprecated.
23
- $blog_id = absint( BLOGID_CURRENT_SITE );
24
- }
25
- $blog_id = ! empty( $blog_id ) ? $blog_id : 1;
26
- }
27
-
28
- return $blog_id;
29
- }
30
- endif;
31
-
32
-
33
- if ( ! function_exists( 'sf_maybe_flush_rewrite_rules' ) ) :
34
- function sf_maybe_flush_rewrite_rules() {
35
- static $done = false;
36
-
37
- if ( did_action( 'init' ) ) {
38
- flush_rewrite_rules();
39
- } elseif ( ! $done ) {
40
- $done = true;
41
- add_action( 'init', 'flush_rewrite_rules', PHP_INT_MAX );
42
- }
43
- }
44
- endif;
45
-
46
-
47
- // Back-compat WP < 3.6.
48
-
49
- if ( ! function_exists( 'wp_is_writable' ) ) :
50
- function wp_is_writable( $path ) {
51
- if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) {
52
- return win_is_writable( $path );
53
- }
54
- return @is_writable( $path );
55
- }
56
- endif;
57
-
58
-
59
  /*------------------------------------------------------------------------------------------------*/
60
  /* !LINKS IN THE PLUGIN ROW ===================================================================== */
61
  /*------------------------------------------------------------------------------------------------*/
62
 
63
- add_filter( 'plugin_action_links_' . SFML_PLUGIN_BASENAME, 'sfml_settings_action_links', 10, 2 );
64
- add_filter( 'network_admin_plugin_action_links_' . SFML_PLUGIN_BASENAME, 'sfml_settings_action_links', 10, 2 );
65
-
66
- function sfml_settings_action_links( $links, $file ) {
 
 
 
 
 
 
 
 
 
67
  $links['settings'] = '<a href="' . esc_url( is_multisite() ? network_admin_url( 'settings.php?page=move-login' ) : admin_url( 'options-general.php?page=move-login' ) ) . '">' . __( 'Settings' ) . '</a>';
68
  return $links;
69
  }
70
 
71
 
72
- // !List everybody, so no one will be jalous. :)
73
-
74
  add_filter( 'plugin_row_meta', 'sfml_plugin_row_meta', 10, 2 );
75
-
 
 
 
 
 
 
 
76
  function sfml_plugin_row_meta( $plugin_meta, $plugin_file ) {
 
 
 
77
 
78
- if ( SFML_PLUGIN_BASENAME === $plugin_file ) {
79
- $pos = false;
80
- $links = array();
81
- $authors = array(
82
- array( 'name' => 'Grégory Viguier', 'url' => 'https://www.screenfeed.fr/' ),
83
- array( 'name' => 'Julio Potier', 'url' => 'http://www.boiteaweb.fr' ),
84
- array( 'name' => 'SecuPress', 'url' => 'http://blog.secupress.fr' ),
85
- );
86
-
87
- if ( ! empty( $plugin_meta ) ) {
88
- $search = '"https://www.screenfeed.fr/"';
89
- foreach ( $plugin_meta as $i => $meta ) {
90
- if ( false !== strpos( $meta, $search ) ) {
91
- $pos = $i;
92
- break;
93
- }
94
  }
95
  }
 
96
 
97
- foreach ( $authors as $author ) {
98
- $links[] = sprintf( '<a href="%s">%s</a>', $author['url'], $author['name'] );
99
- }
100
 
101
- $links = sprintf( __( 'By %s' ), wp_sprintf( '%l', $links ) );
102
 
103
- if ( false !== $pos ) {
104
- $plugin_meta[ $pos ] = $links;
105
- } else {
106
- $plugin_meta[] = $links;
107
- }
108
  }
109
 
110
  return $plugin_meta;
@@ -115,8 +78,14 @@ function sfml_plugin_row_meta( $plugin_meta, $plugin_file ) {
115
  /* !MENU ITEM =================================================================================== */
116
  /*------------------------------------------------------------------------------------------------*/
117
 
118
- add_action( ( is_multisite() ? 'network_' : '' ) . 'admin_menu', 'sfml_admin_menu' );
119
-
 
 
 
 
 
 
120
  function sfml_admin_menu() {
121
  $page = is_multisite() ? 'settings.php' : 'options-general.php';
122
  $cap = is_multisite() ? 'manage_network_options' : 'manage_options';
@@ -128,12 +97,16 @@ function sfml_admin_menu() {
128
  /* !SETTINGS PAGE =============================================================================== */
129
  /*------------------------------------------------------------------------------------------------*/
130
 
131
- // !Include the settings page file on... the settings page.
132
-
133
  add_action( 'load-settings_page_' . SFML_Options::OPTION_PAGE, 'sfml_include_settings_page' );
134
-
 
 
135
  function sfml_include_settings_page() {
136
- include( SFML_PLUGIN_DIR . 'inc/settings-page.php' );
 
 
 
 
137
  }
138
 
139
 
@@ -141,12 +114,31 @@ function sfml_include_settings_page() {
141
  /* !SAVE SETTINGS ON FORM SUBMIT ================================================================ */
142
  /*------------------------------------------------------------------------------------------------*/
143
 
144
- // !options.php do not handle site options. Let's use admin-post.php for multisite installations.
145
-
146
  if ( is_multisite() ) :
147
 
148
- add_action( 'admin_post_update', 'sfml_update_site_option_on_submit' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
 
 
 
 
 
150
  function sfml_update_site_option_on_submit() {
151
  $option_group = SFML_Options::OPTION_GROUP;
152
 
@@ -162,7 +154,12 @@ if ( is_multisite() ) :
162
 
163
  check_admin_referer( $option_group . '-options' );
164
 
165
- $whitelist_options = apply_filters( 'whitelist_options', array() );
 
 
 
 
 
166
 
167
  if ( ! isset( $whitelist_options[ $option_group ] ) ) {
168
  wp_die( __( '<strong>ERROR</strong>: options page not found.' ) );
@@ -188,7 +185,7 @@ if ( is_multisite() ) :
188
  }
189
 
190
  /**
191
- * Handle settings errors and return to options page
192
  */
193
  // If no settings errors were registered add a general 'updated' message.
194
  if ( ! count( get_settings_errors() ) ) {
@@ -197,10 +194,10 @@ if ( is_multisite() ) :
197
  set_transient( 'settings_errors', get_settings_errors(), 30 );
198
 
199
  /**
200
- * Redirect back to the settings page that was submitted
201
  */
202
- $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() );
203
- wp_redirect( $goback );
204
  exit;
205
  }
206
 
@@ -211,18 +208,19 @@ endif;
211
  /* !UPGRADE ===================================================================================== */
212
  /*------------------------------------------------------------------------------------------------*/
213
 
214
- // !Delete previous options.
215
-
 
216
  function sfml_delete_noop_options() {
217
  $option_name = 'sfml';
218
  $page_name = 'move-login';
219
  $page_parent_name = 'settings';
220
 
221
- // Remove the main option and the history option
222
  delete_option( $option_name );
223
  delete_option( $option_name . '_history' );
224
 
225
- // Remove the users metadatas, reguarding the metaboxes placement
226
  delete_metadata( 'user', 0, 'screen_layout_' . $page_parent_name . '_page_' . $page_name, null, true );
227
  delete_metadata( 'user', 0, 'metaboxhidden_' . $page_parent_name . '_page_' . $page_name, null, true );
228
  delete_metadata( 'user', 0, 'meta-box-order_' . $page_parent_name . '_page_' . $page_name, null, true );
@@ -237,15 +235,17 @@ function sfml_delete_noop_options() {
237
  }
238
 
239
 
240
- // !Upgrade
241
-
 
242
  function sfml_upgrade() {
243
  $proceed = false;
244
- $mono_or_multi = 0; // Used to tell if the site changed from monosite to multisite.
245
- $current_mono_multi = is_multisite() ? 2 : 1; // 1: monosite, 2: multisite.
 
 
246
  $db_version = get_site_option( 'sfml_version' );
247
  $db_version = is_string( $db_version ) ? explode( '|', $db_version ) : false;
248
- // `$update_file`:
249
  // "1" means we need to update the `.htaccess`/`web.config` file.
250
  // "2" means "No need to update the `.htaccess`/`web.config` file": update_site_option() already did.
251
  $update_file = false;
@@ -268,14 +268,13 @@ function sfml_upgrade() {
268
 
269
  // < 2.0 (old version with Noop)
270
  if ( ! $mono_or_multi || version_compare( $db_version, '2.0' ) < 0 ) {
271
-
272
  // < 1.1
273
  if ( ! $db_version ) {
274
- sf_maybe_flush_rewrite_rules();
275
  }
276
 
277
- if ( is_multisite() && get_main_blog_id() !== get_current_blog_id() ) {
278
- switch_to_blog( get_main_blog_id() );
279
  $old_options = get_option( 'sfml' );
280
  sfml_delete_noop_options();
281
  restore_current_blog();
@@ -290,18 +289,15 @@ function sfml_upgrade() {
290
 
291
  update_site_option( SFML_Options::OPTION_NAME, $old_options );
292
  $update_file = '2';
293
-
294
  }
295
  // Switched monosite ==> multisite since the last check.
296
  elseif ( $mono_or_multi !== $current_mono_multi && 2 === $current_mono_multi ) {
297
-
298
  $old_options = get_option( 'sfml' );
299
  $old_options = is_array( $old_options ) ? $old_options : array();
300
  delete_option( 'sfml' );
301
 
302
  update_site_option( SFML_Options::OPTION_NAME, $old_options );
303
  $update_file = '2';
304
-
305
  }
306
  // There are some changes in the stored options.
307
  elseif ( version_compare( $db_version, '2.2.1' ) < 0 ) {
@@ -312,7 +308,7 @@ function sfml_upgrade() {
312
 
313
  // Maybe display a notice, but only if the `.htaccess`/`web.config` file needs to be updated.
314
  if ( $update_file ) {
315
- set_transient( 'sfml_notices-' . get_current_user_id(), $update_file );
316
  }
317
 
318
  update_site_option( 'sfml_version', SFML_VERSION . '|' . $current_mono_multi );
@@ -325,46 +321,42 @@ sfml_upgrade();
325
  /* !ADMIN NOTICES + UPDATE REWRITE RULES ======================================================== */
326
  /*------------------------------------------------------------------------------------------------*/
327
 
328
- // !Admin notices
329
-
330
  add_action( 'all_admin_notices', 'sfml_notices' );
331
-
 
 
332
  function sfml_notices() {
333
  global $is_apache, $is_iis7;
334
 
335
- // Get previous notices
336
  $user_id = get_current_user_id();
337
- $proceed = get_transient( 'sfml_notices-' . $user_id ); // 1 means "Update the file". 2 means "No need to update the file".
 
338
 
339
  // If the transient exists, it means it's the plugin activation or upgrade.
340
  if ( ! $proceed ) {
341
  return;
342
  }
343
 
344
- if ( ! function_exists( 'sfml_write_rules' ) ) {
345
- include( SFML_PLUGIN_DIR . 'inc/rewrite.php' );
346
- }
347
-
348
- delete_transient( 'sfml_notices-' . $user_id );
349
 
350
- $notices = array();
351
- $is_nginx = sfml_is_nginx();
352
- $home_path = sfml_get_home_path();
353
 
354
- // IIS7
355
- if ( $is_iis7 && iis7_supports_permalinks() && ! ( wp_is_writable( $home_path . 'web.config' ) || ( ! file_exists( $home_path . 'web.config' ) && wp_is_writable( $home_path ) ) ) ) {
356
  $notices[] = 'error_file_not_writable';
357
  }
358
- // Apache
359
- elseif ( $is_apache && got_mod_rewrite() && ! ( wp_is_writable( $home_path . '.htaccess' ) || ( ! file_exists( $home_path . '.htaccess' ) && wp_is_writable( $home_path ) ) ) ) {
360
  $notices[] = 'error_file_not_writable';
361
  }
362
- // Nginx
363
  elseif ( $is_nginx ) {
364
  $notices[] = 'updated_is_nginx';
365
  }
366
 
367
- // Display notices
368
  if ( ! empty( $notices ) ) {
369
  $messages = array();
370
 
@@ -379,7 +371,8 @@ function sfml_notices() {
379
  echo '<div class="' . $class . '"><p>' . implode( '<br/>', $message ) . '</p></div>';
380
  }
381
  } elseif ( '1' === $proceed ) {
382
- // Add the rewrite rules to the .htaccess/web.config file.
 
383
  sfml_write_rules();
384
  }
385
  }
3
  die( 'Cheatin\' uh?' );
4
  }
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  /*------------------------------------------------------------------------------------------------*/
7
  /* !LINKS IN THE PLUGIN ROW ===================================================================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
+ if ( is_multisite() ) {
11
+ add_filter( 'network_admin_plugin_action_links_' . SFML_PLUGIN_BASENAME, 'sfml_settings_action_links' );
12
+ } else {
13
+ add_filter( 'plugin_action_links_' . SFML_PLUGIN_BASENAME, 'sfml_settings_action_links' );
14
+ }
15
+ /**
16
+ * Add a "Settings" link to the plugin row.
17
+ *
18
+ * @param (array) $links An array of links.
19
+ *
20
+ * @return (array) The array of links + our link.
21
+ */
22
+ function sfml_settings_action_links( $links ) {
23
  $links['settings'] = '<a href="' . esc_url( is_multisite() ? network_admin_url( 'settings.php?page=move-login' ) : admin_url( 'options-general.php?page=move-login' ) ) . '">' . __( 'Settings' ) . '</a>';
24
  return $links;
25
  }
26
 
27
 
 
 
28
  add_filter( 'plugin_row_meta', 'sfml_plugin_row_meta', 10, 2 );
29
+ /**
30
+ * List everybody in the plugin row, so no one will be jalous.
31
+ *
32
+ * @param (array) $plugin_meta An array of HTML links.
33
+ * @param (string) $plugin_file A plugin basename.
34
+ *
35
+ * @return (array) The array of links + our links.
36
+ */
37
  function sfml_plugin_row_meta( $plugin_meta, $plugin_file ) {
38
+ if ( SFML_PLUGIN_BASENAME !== $plugin_file ) {
39
+ return $plugin_meta;
40
+ }
41
 
42
+ $pos = false;
43
+ $links = array();
44
+ $authors = array(
45
+ array( 'name' => 'Grégory Viguier', 'url' => 'https://www.screenfeed.fr/' ),
46
+ array( 'name' => 'SecuPress', 'url' => 'https://secupress.me/' ),
47
+ array( 'name' => 'Julio Potier', 'url' => 'http://www.boiteaweb.fr' ),
48
+ );
49
+
50
+ if ( $plugin_meta ) {
51
+ $search = '"https://www.screenfeed.fr/"';
52
+
53
+ foreach ( $plugin_meta as $i => $meta ) {
54
+ if ( false !== strpos( $meta, $search ) ) {
55
+ $pos = $i;
56
+ break;
 
57
  }
58
  }
59
+ }
60
 
61
+ foreach ( $authors as $author ) {
62
+ $links[] = sprintf( '<a href="%s">%s</a>', $author['url'], $author['name'] );
63
+ }
64
 
65
+ $links = sprintf( __( 'By %s' ), wp_sprintf( '%l', $links ) );
66
 
67
+ if ( false !== $pos ) {
68
+ $plugin_meta[ $pos ] = $links;
69
+ } else {
70
+ $plugin_meta[] = $links;
 
71
  }
72
 
73
  return $plugin_meta;
78
  /* !MENU ITEM =================================================================================== */
79
  /*------------------------------------------------------------------------------------------------*/
80
 
81
+ if ( is_multisite() ) {
82
+ add_filter( 'network_admin_menu', 'sfml_admin_menu' );
83
+ } else {
84
+ add_filter( 'admin_menu', 'sfml_admin_menu' );
85
+ }
86
+ /**
87
+ * Create the plugin submenu.
88
+ */
89
  function sfml_admin_menu() {
90
  $page = is_multisite() ? 'settings.php' : 'options-general.php';
91
  $cap = is_multisite() ? 'manage_network_options' : 'manage_options';
97
  /* !SETTINGS PAGE =============================================================================== */
98
  /*------------------------------------------------------------------------------------------------*/
99
 
 
 
100
  add_action( 'load-settings_page_' . SFML_Options::OPTION_PAGE, 'sfml_include_settings_page' );
101
+ /**
102
+ * Include the settings page file on... the settings page.
103
+ */
104
  function sfml_include_settings_page() {
105
+ include_once( SFML_PLUGIN_DIR . 'inc/functions/settings-page.php' );
106
+
107
+ add_action( 'all_admin_notices', 'sfml_shunt_options_settings_errors', PHP_INT_MAX );
108
+
109
+ sfml_settings_fields();
110
  }
111
 
112
 
114
  /* !SAVE SETTINGS ON FORM SUBMIT ================================================================ */
115
  /*------------------------------------------------------------------------------------------------*/
116
 
 
 
117
  if ( is_multisite() ) :
118
 
119
+ add_filter( 'sfml_whitelist_network_options', 'sfml_network_option_update_filter' );
120
+ /**
121
+ * Whitelist network options added with `SFML_Options::register_setting()`.
122
+ *
123
+ * @param (array) $options Other whitelisted options.
124
+ *
125
+ * @return (array)
126
+ */
127
+ function sfml_network_option_update_filter( $options ) {
128
+ $whitelist = sfml_cache_data( 'new_whitelist_network_options' );
129
+
130
+ if ( is_array( $whitelist ) ) {
131
+ $options = add_option_whitelist( $whitelist, $options );
132
+ }
133
+
134
+ return $options;
135
+ }
136
 
137
+
138
+ add_action( 'admin_post_update', 'sfml_update_site_option_on_submit' );
139
+ /**
140
+ * `options.php` do not handle site options. Let's use admin-post.php for multisite installations.
141
+ */
142
  function sfml_update_site_option_on_submit() {
143
  $option_group = SFML_Options::OPTION_GROUP;
144
 
154
 
155
  check_admin_referer( $option_group . '-options' );
156
 
157
+ /**
158
+ * Add network options to whitelist.
159
+ *
160
+ * @param (array) $whitelist_options Network option names, grouped by option groups. By default an empty array.
161
+ */
162
+ $whitelist_options = apply_filters( 'sfml_whitelist_network_options', array() );
163
 
164
  if ( ! isset( $whitelist_options[ $option_group ] ) ) {
165
  wp_die( __( '<strong>ERROR</strong>: options page not found.' ) );
185
  }
186
 
187
  /**
188
+ * Handle settings errors and return to options page.
189
  */
190
  // If no settings errors were registered add a general 'updated' message.
191
  if ( ! count( get_settings_errors() ) ) {
194
  set_transient( 'settings_errors', get_settings_errors(), 30 );
195
 
196
  /**
197
+ * Redirect back to the settings page that was submitted.
198
  */
199
+ $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() );
200
+ wp_redirect( esc_url_raw( $goback ) );
201
  exit;
202
  }
203
 
208
  /* !UPGRADE ===================================================================================== */
209
  /*------------------------------------------------------------------------------------------------*/
210
 
211
+ /**
212
+ * Delete previous options.
213
+ */
214
  function sfml_delete_noop_options() {
215
  $option_name = 'sfml';
216
  $page_name = 'move-login';
217
  $page_parent_name = 'settings';
218
 
219
+ // Remove the main option and the history option.
220
  delete_option( $option_name );
221
  delete_option( $option_name . '_history' );
222
 
223
+ // Remove the users metadatas, reguarding the metaboxes placement.
224
  delete_metadata( 'user', 0, 'screen_layout_' . $page_parent_name . '_page_' . $page_name, null, true );
225
  delete_metadata( 'user', 0, 'metaboxhidden_' . $page_parent_name . '_page_' . $page_name, null, true );
226
  delete_metadata( 'user', 0, 'meta-box-order_' . $page_parent_name . '_page_' . $page_name, null, true );
235
  }
236
 
237
 
238
+ /**
239
+ * Upgrade.
240
+ */
241
  function sfml_upgrade() {
242
  $proceed = false;
243
+ // Used to tell if the site changed from monosite to multisite.
244
+ $mono_or_multi = 0;
245
+ // 1: monosite, 2: multisite.
246
+ $current_mono_multi = is_multisite() ? 2 : 1;
247
  $db_version = get_site_option( 'sfml_version' );
248
  $db_version = is_string( $db_version ) ? explode( '|', $db_version ) : false;
 
249
  // "1" means we need to update the `.htaccess`/`web.config` file.
250
  // "2" means "No need to update the `.htaccess`/`web.config` file": update_site_option() already did.
251
  $update_file = false;
268
 
269
  // < 2.0 (old version with Noop)
270
  if ( ! $mono_or_multi || version_compare( $db_version, '2.0' ) < 0 ) {
 
271
  // < 1.1
272
  if ( ! $db_version ) {
273
+ sfml_maybe_flush_rewrite_rules();
274
  }
275
 
276
+ if ( is_multisite() && sfml_get_main_blog_id() !== get_current_blog_id() ) {
277
+ switch_to_blog( sfml_get_main_blog_id() );
278
  $old_options = get_option( 'sfml' );
279
  sfml_delete_noop_options();
280
  restore_current_blog();
289
 
290
  update_site_option( SFML_Options::OPTION_NAME, $old_options );
291
  $update_file = '2';
 
292
  }
293
  // Switched monosite ==> multisite since the last check.
294
  elseif ( $mono_or_multi !== $current_mono_multi && 2 === $current_mono_multi ) {
 
295
  $old_options = get_option( 'sfml' );
296
  $old_options = is_array( $old_options ) ? $old_options : array();
297
  delete_option( 'sfml' );
298
 
299
  update_site_option( SFML_Options::OPTION_NAME, $old_options );
300
  $update_file = '2';
 
301
  }
302
  // There are some changes in the stored options.
303
  elseif ( version_compare( $db_version, '2.2.1' ) < 0 ) {
308
 
309
  // Maybe display a notice, but only if the `.htaccess`/`web.config` file needs to be updated.
310
  if ( $update_file ) {
311
+ set_transient( 'sfml_activation-' . get_current_user_id(), $update_file );
312
  }
313
 
314
  update_site_option( 'sfml_version', SFML_VERSION . '|' . $current_mono_multi );
321
  /* !ADMIN NOTICES + UPDATE REWRITE RULES ======================================================== */
322
  /*------------------------------------------------------------------------------------------------*/
323
 
 
 
324
  add_action( 'all_admin_notices', 'sfml_notices' );
325
+ /**
326
+ * Admin notices or write initial rules.
327
+ */
328
  function sfml_notices() {
329
  global $is_apache, $is_iis7;
330
 
331
+ // Get previous notices.
332
  $user_id = get_current_user_id();
333
+ // 1 means "Update the file". 2 means "No need to update the file".
334
+ $proceed = get_transient( 'sfml_activation-' . $user_id );
335
 
336
  // If the transient exists, it means it's the plugin activation or upgrade.
337
  if ( ! $proceed ) {
338
  return;
339
  }
340
 
341
+ delete_transient( 'sfml_activation-' . $user_id );
 
 
 
 
342
 
343
+ $notices = array();
344
+ $is_nginx = sfml_is_nginx();
 
345
 
346
+ // IIS7.
347
+ if ( $is_iis7 && ! sfml_can_write_file() ) {
348
  $notices[] = 'error_file_not_writable';
349
  }
350
+ // Apache.
351
+ elseif ( $is_apache && ! sfml_can_write_file() ) {
352
  $notices[] = 'error_file_not_writable';
353
  }
354
+ // Nginx.
355
  elseif ( $is_nginx ) {
356
  $notices[] = 'updated_is_nginx';
357
  }
358
 
359
+ // Display notices.
360
  if ( ! empty( $notices ) ) {
361
  $messages = array();
362
 
371
  echo '<div class="' . $class . '"><p>' . implode( '<br/>', $message ) . '</p></div>';
372
  }
373
  } elseif ( '1' === $proceed ) {
374
+ sfml_include_rewrite_file();
375
+ // Add the rewrite rules to the `.htaccess`/`web.config` file.
376
  sfml_write_rules();
377
  }
378
  }
inc/class-sfml-options.php DELETED
@@ -1,350 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) {
3
- die( 'Cheatin\' uh?' );
4
- }
5
-
6
- /*------------------------------------------------------------------------------------------------*/
7
- /* !CLASS BEARING THE MECHANISM FOR OPTIONS ===================================================== */
8
- /*------------------------------------------------------------------------------------------------*/
9
-
10
- class SFML_Options {
11
-
12
- const VERSION = '1.1';
13
- const OPTION_NAME = 'sfml';
14
- const OPTION_GROUP = 'sfml_settings';
15
- const OPTION_PAGE = 'move-login';
16
-
17
- protected static $options;
18
- protected static $options_default;
19
- protected static $slugs;
20
- protected static $labels;
21
-
22
-
23
- // !Init
24
-
25
- public static function init() {
26
- static $done = false;
27
-
28
- if ( defined( 'WP_UNINSTALL_PLUGIN' ) || $done ) {
29
- return;
30
- }
31
-
32
- $done = true;
33
-
34
- // Register option and sanitization method.
35
- self::register_setting( array( __CLASS__, 'sanitize_options' ) );
36
- }
37
-
38
-
39
- // !Get default options
40
-
41
- public static function get_default_options() {
42
-
43
- self::maybe_clear_options_cache();
44
-
45
- if ( ! isset( self::$options_default ) ) {
46
- // Default slugs.
47
- self::$options_default = array(
48
- 'slugs.postpass' => 'postpass',
49
- 'slugs.logout' => 'logout',
50
- 'slugs.lostpassword' => 'lostpassword',
51
- 'slugs.resetpass' => 'resetpass',
52
- 'slugs.register' => 'register',
53
- 'slugs.login' => 'login',
54
- );
55
-
56
- // Plugins can add their own actions.
57
- $additional_slugs = apply_filters( 'sfml_additional_slugs', array() );
58
-
59
- if ( $additional_slugs && is_array( $additional_slugs ) ) {
60
- foreach ( $additional_slugs as $slug_key => $slug_label ) {
61
- $slug_key = sanitize_title( $slug_key, '', 'display' );
62
-
63
- if ( ! empty( $slug_key ) && ! isset( self::$options_default[ 'slug.' . $slug_key ] ) ) {
64
- self::$options_default[ 'slugs.' . $slug_key ] = $slug_key;
65
- }
66
- }
67
- }
68
-
69
- // Options
70
- self::$options_default = array_merge( self::$options_default, array(
71
- 'deny_wp_login_access' => 1,
72
- 'deny_admin_access' => 0,
73
- ) );
74
-
75
- }
76
-
77
- return self::$options_default;
78
- }
79
-
80
-
81
- // !Get all options
82
-
83
- public static function get_options() {
84
-
85
- self::maybe_clear_options_cache();
86
-
87
- if ( ! isset( self::$options ) ) {
88
- self::$options = array();
89
- $old_options = get_site_option( self::OPTION_NAME );
90
- $defaults = self::get_default_options();
91
-
92
- if ( is_array( $old_options ) ) {
93
- $default_slugs = self::get_sub_options( 'slugs', $defaults );
94
-
95
- // Add and escape slugs
96
- foreach ( $default_slugs as $slug_key => $default_slug ) {
97
- self::$options[ 'slugs.' . $slug_key ] = ! empty( $old_options[ 'slugs.' . $slug_key ] ) ? sanitize_title( $old_options[ 'slugs.' . $slug_key ], $default_slug, 'display' ) : $default_slug;
98
- }
99
-
100
- // Add and escape other options
101
- if ( isset( $defaults['deny_wp_login_access'] ) ) {
102
- self::$options['deny_wp_login_access'] = isset( $old_options['deny_wp_login_access'] ) ? min( 3, max( 1, (int) $old_options['deny_wp_login_access'] ) ) : $defaults['deny_wp_login_access'];
103
- }
104
-
105
- if ( isset( $defaults['deny_admin_access'] ) ) {
106
- self::$options['deny_admin_access'] = isset( $old_options['deny_admin_access'] ) ? min( 3, max( 0, (int) $old_options['deny_admin_access'] ) ) : $defaults['deny_admin_access'];
107
- }
108
- } else {
109
- self::$options = $defaults;
110
- }
111
-
112
- // Generic filter, change the values.
113
- $options_tmp = apply_filters( 'sfml_options', self::$options );
114
- self::$options = array_intersect_key( array_merge( self::$options, $options_tmp ), self::$options ); // Make sure no keys have been added or removed.
115
- }
116
-
117
- return self::$options;
118
- }
119
-
120
-
121
- // !Get the slugs
122
-
123
- public static function get_slugs() {
124
-
125
- self::maybe_clear_options_cache();
126
-
127
- if ( ! isset( self::$slugs ) ) {
128
- self::$slugs = self::get_sub_options( 'slugs', self::get_options() );
129
- }
130
-
131
- return self::$slugs;
132
- }
133
-
134
-
135
- // !Sanitize options on save
136
-
137
- public static function sanitize_options( $options = array() ) {
138
-
139
- $out = array();
140
- $errors = array( 'forbidden' => array(), 'duplicates' => array() );
141
- $old_options = get_site_option( self::OPTION_NAME );
142
- $defaults = self::get_default_options();
143
-
144
- // Add and sanitize slugs
145
- $default_slugs = self::get_sub_options( 'slugs', $defaults );
146
- $exclude = self::get_other_actions();
147
-
148
- foreach ( $default_slugs as $slug_key => $default_slug ) {
149
-
150
- if ( isset( $exclude[ $slug_key ] ) ) {
151
- $out[ 'slugs.' . $slug_key ] = $exclude[ $slug_key ];
152
- continue;
153
- }
154
-
155
- $out[ 'slugs.' . $slug_key ] = false;
156
-
157
- if ( ! empty( $options[ 'slugs.' . $slug_key ] ) ) {
158
- $tmp_slug = sanitize_title( $options[ 'slugs.' . $slug_key ], $default_slug );
159
-
160
- // postpass, retrievepassword and rp are forbidden.
161
- if ( in_array( $tmp_slug, $exclude ) ) {
162
- $errors['forbidden'][] = $tmp_slug;
163
- }
164
- // Make sure the slug is not already set for another action.
165
- elseif ( in_array( $tmp_slug, $out ) ) {
166
- $errors['duplicates'][] = $tmp_slug;
167
- }
168
- // Yay!
169
- else {
170
- $out[ 'slugs.' . $slug_key ] = $tmp_slug;
171
- }
172
- }
173
-
174
- // Fallback to old value or default value.
175
- if ( ! $out[ 'slugs.' . $slug_key ] ) {
176
- if ( ! isset( $exclude[ $slug_key ] ) && ! empty( $old_options[ 'slugs.' . $slug_key ] ) ) {
177
- $out[ 'slugs.' . $slug_key ] = sanitize_title( $old_options[ 'slugs.' . $slug_key ], $default_slug );
178
- } else {
179
- $out[ 'slugs.' . $slug_key ] = $default_slug;
180
- }
181
- }
182
- }
183
-
184
- // Add and sanitize other options
185
- if ( isset( $defaults['deny_wp_login_access'] ) ) {
186
- if ( isset( $options['deny_wp_login_access'] ) ) {
187
-
188
- $out['deny_wp_login_access'] = min( 3, max( 1, (int) $options['deny_wp_login_access'] ) );
189
-
190
- } elseif ( isset( $old_options['deny_wp_login_access'] ) ) {
191
-
192
- $out['deny_wp_login_access'] = min( 3, max( 1, (int) $old_options['deny_wp_login_access'] ) );
193
-
194
- } else {
195
-
196
- $out['deny_wp_login_access'] = $defaults['deny_wp_login_access'];
197
-
198
- }
199
- }
200
-
201
- if ( isset( $defaults['deny_admin_access'] ) ) {
202
- if ( isset( $options['deny_admin_access'] ) ) {
203
-
204
- $out['deny_admin_access'] = min( 3, max( 0, (int) $options['deny_admin_access'] ) );
205
-
206
- } elseif ( isset( $old_options['deny_admin_access'] ) ) {
207
-
208
- $out['deny_admin_access'] = min( 3, max( 0, (int) $old_options['deny_admin_access'] ) );
209
-
210
- } else {
211
-
212
- $out['deny_admin_access'] = $defaults['deny_admin_access'];
213
-
214
- }
215
- }
216
-
217
- // Generic filter, change the values.
218
- $options_tmp = apply_filters( 'sfml_sanitize_options', $out, $options );
219
- $out = array_merge( $out, $options_tmp ); // Make sure no keys have been removed.
220
-
221
- // Clear options cache.
222
- self::maybe_clear_options_cache( true );
223
-
224
- // Add the rewrite rules to the .htaccess/web.config file.
225
- $old_slugs = self::get_sub_options( 'slugs', $old_options );
226
- $new_slugs = self::get_sub_options( 'slugs', $out );
227
-
228
- if ( $old_slugs !== $new_slugs ) {
229
- if ( ! function_exists( 'sfml_write_rules' ) ) {
230
- include( SFML_PLUGIN_DIR . 'inc/rewrite.php' );
231
- }
232
-
233
- sfml_write_rules( sfml_rules( $new_slugs ) );
234
- }
235
-
236
- // Trigger errors
237
- if ( is_admin() ) {
238
- $errors['forbidden'] = array_unique( $errors['forbidden'] );
239
- $errors['duplicates'] = array_unique( $errors['duplicates'] );
240
-
241
- if ( $nbr_forbidden = count( $errors['forbidden'] ) ) {
242
- add_settings_error( 'sfml_settings', 'forbidden-slugs', sprintf( _n( 'The slug %s is forbidden.', 'The slugs %s are forbidden.', $nbr_forbidden, 'sf-move-login' ), wp_sprintf( '<code>%l</code>', $errors['forbidden'] ) ) );
243
- }
244
- if ( ! empty( $errors['duplicates'] ) ) {
245
- add_settings_error( 'sfml_settings', 'duplicates-slugs', __( 'The links can\'t have the same slugs.', 'sf-move-login' ) );
246
- }
247
- }
248
-
249
- return $out;
250
- }
251
-
252
-
253
- // !Get sub-options.
254
-
255
- public static function get_sub_options( $name = false, $options = array() ) {
256
- if ( empty( $options ) || ! $name ) {
257
- return array();
258
- }
259
-
260
- $options = (array) $options;
261
-
262
- if ( isset( $options[ $name ] ) ) {
263
- return $options[ $name ];
264
- }
265
-
266
- $group = array();
267
- $name = rtrim( $name, '.' ) . '.';
268
-
269
- foreach ( $options as $k => $v ) {
270
- if ( 0 === strpos( $k, $name ) ) {
271
- $group[ substr( $k, strlen( $name ) ) ] = $v;
272
- }
273
- }
274
-
275
- return ! empty( $group ) ? $group : null;
276
- }
277
-
278
-
279
- // !Fields labels (for the slugs)
280
-
281
- public static function slugs_fields_labels() {
282
-
283
- self::maybe_clear_options_cache();
284
-
285
- if ( ! isset( self::$labels ) ) {
286
- self::$labels = array(
287
- 'login' => __( 'Log in' ),
288
- 'logout' => __( 'Log out' ),
289
- 'register' => __( 'Register' ),
290
- 'lostpassword' => __( 'Lost Password' ),
291
- 'resetpass' => __( 'Password Reset' ),
292
- );
293
-
294
- // Plugins can add their own actions.
295
- $new_slugs = apply_filters( 'sfml_additional_slugs', array() );
296
-
297
- if ( ! empty( $new_slugs ) ) {
298
- $new_slugs = array_diff_key( $new_slugs, self::$labels );
299
- self::$labels = array_merge( self::$labels, $new_slugs );
300
- }
301
- }
302
-
303
- return self::$labels;
304
- }
305
-
306
-
307
- // !Return the "other" original login actions: not the ones listed in our settings.
308
-
309
- public static function get_other_actions() {
310
- return array_diff_key( array(
311
- 'retrievepassword' => 'retrievepassword',
312
- 'rp' => 'rp',
313
- ), self::slugs_fields_labels() );
314
- }
315
-
316
-
317
- // !Clear options cache
318
-
319
- public static function maybe_clear_options_cache( $force = false ) {
320
- if ( $force || apply_filters( self::OPTION_NAME . '_clear_options_cache', false ) ) {
321
- self::$options = null;
322
- self::$options_default = null;
323
- self::$slugs = null;
324
- self::$labels = null;
325
- remove_all_filters( self::OPTION_NAME . '_clear_options_cache' );
326
- }
327
- }
328
-
329
-
330
- // !register_setting() is not always defined...
331
-
332
- protected static function register_setting( $sanitize_callback = '' ) {
333
- global $new_whitelist_options;
334
-
335
- if ( is_admin() ) {
336
- if ( function_exists( 'register_setting' ) ) {
337
- register_setting( self::OPTION_GROUP, self::OPTION_NAME, $sanitize_callback );
338
- return;
339
- }
340
-
341
- $new_whitelist_options = isset( $new_whitelist_options ) && is_array( $new_whitelist_options ) ? $new_whitelist_options : array(); // WPCS: override ok.
342
- $new_whitelist_options[ self::OPTION_GROUP ] = isset( $new_whitelist_options[ self::OPTION_GROUP ] ) && is_array( $new_whitelist_options[ self::OPTION_GROUP ] ) ? $new_whitelist_options[ self::OPTION_GROUP ] : array();
343
- $new_whitelist_options[ self::OPTION_GROUP ][] = self::OPTION_NAME;
344
- }
345
-
346
- if ( ! $sanitize_callback ) {
347
- add_filter( 'sanitize_option_' . self::OPTION_NAME, $sanitize_callback );
348
- }
349
- }
350
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/classes/class-sfml-options.php ADDED
@@ -0,0 +1,460 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /**
7
+ * Singleton class.
8
+ *
9
+ * @package Move Login
10
+ */
11
+ class SFML_Options extends SFML_Singleton {
12
+
13
+ const VERSION = '1.2';
14
+ const OPTION_NAME = 'sfml';
15
+ const OPTION_GROUP = 'sfml_settings';
16
+ const OPTION_PAGE = 'move-login';
17
+
18
+ /**
19
+ * Options.
20
+ *
21
+ * @var (array)
22
+ */
23
+ protected $options;
24
+
25
+ /**
26
+ * Default options.
27
+ *
28
+ * @var (array)
29
+ */
30
+ protected $options_default;
31
+
32
+ /**
33
+ * Slugs.
34
+ *
35
+ * @var (array)
36
+ */
37
+ protected $slugs;
38
+
39
+ /**
40
+ * Setting labels.
41
+ *
42
+ * @var (array)
43
+ */
44
+ protected $labels;
45
+
46
+
47
+ /**
48
+ * Init.
49
+ */
50
+ public function _init() {
51
+ if ( defined( 'WP_UNINSTALL_PLUGIN' ) ) {
52
+ return;
53
+ }
54
+
55
+ // Register option and sanitization method.
56
+ $this->register_setting();
57
+ }
58
+
59
+
60
+ /**
61
+ * Get default options.
62
+ *
63
+ * @return (array)
64
+ */
65
+ public function get_default_options() {
66
+ $this->maybe_clear_options_cache();
67
+
68
+ if ( isset( $this->options_default ) ) {
69
+ return $this->options_default;
70
+ }
71
+
72
+ // Default slugs.
73
+ $this->options_default = array(
74
+ 'slugs.postpass' => 'postpass',
75
+ 'slugs.logout' => 'logout',
76
+ 'slugs.lostpassword' => 'lostpassword',
77
+ 'slugs.resetpass' => 'resetpass',
78
+ 'slugs.register' => 'register',
79
+ 'slugs.login' => 'login',
80
+ );
81
+
82
+ // Plugins can add their own actions.
83
+ $additional_slugs = static::get_additional_labels();
84
+
85
+ if ( $additional_slugs && is_array( $additional_slugs ) ) {
86
+ foreach ( $additional_slugs as $slug_key => $slug_label ) {
87
+ $slug_key = sanitize_title( $slug_key, '', 'display' );
88
+
89
+ if ( ! empty( $slug_key ) && ! isset( $this->options_default[ 'slug.' . $slug_key ] ) ) {
90
+ $this->options_default[ 'slugs.' . $slug_key ] = $slug_key;
91
+ }
92
+ }
93
+ }
94
+
95
+ // Options.
96
+ $this->options_default = array_merge( $this->options_default, array(
97
+ 'deny_wp_login_access' => 1,
98
+ 'deny_admin_access' => 0,
99
+ ) );
100
+
101
+ return $this->options_default;
102
+ }
103
+
104
+
105
+ /**
106
+ * Get all options.
107
+ *
108
+ * @return (array)
109
+ */
110
+ public function get_options() {
111
+ $this->maybe_clear_options_cache();
112
+
113
+ if ( isset( $this->options ) ) {
114
+ return $this->options;
115
+ }
116
+
117
+ $this->options = array();
118
+ $old_options = get_site_option( static::OPTION_NAME );
119
+ $defaults = $this->get_default_options();
120
+
121
+ if ( is_array( $old_options ) ) {
122
+ $default_slugs = static::get_sub_options( 'slugs', $defaults );
123
+
124
+ // Add and escape slugs.
125
+ foreach ( $default_slugs as $slug_key => $default_slug ) {
126
+ $this->options[ 'slugs.' . $slug_key ] = ! empty( $old_options[ 'slugs.' . $slug_key ] ) ? sanitize_title( $old_options[ 'slugs.' . $slug_key ], $default_slug, 'display' ) : $default_slug;
127
+ }
128
+
129
+ // Add and escape other options.
130
+ if ( isset( $defaults['deny_wp_login_access'] ) ) {
131
+ $this->options['deny_wp_login_access'] = isset( $old_options['deny_wp_login_access'] ) ? min( 3, max( 1, (int) $old_options['deny_wp_login_access'] ) ) : $defaults['deny_wp_login_access'];
132
+ }
133
+
134
+ if ( isset( $defaults['deny_admin_access'] ) ) {
135
+ $this->options['deny_admin_access'] = isset( $old_options['deny_admin_access'] ) ? min( 3, max( 0, (int) $old_options['deny_admin_access'] ) ) : $defaults['deny_admin_access'];
136
+ }
137
+ } else {
138
+ $this->options = $defaults;
139
+ }
140
+
141
+ // Generic filter, change the values.
142
+ $options_tmp = apply_filters( 'sfml_options', $this->options );
143
+ // Make sure no keys have been added or removed.
144
+ $this->options = array_intersect_key( array_merge( $this->options, $options_tmp ), $this->options );
145
+
146
+ return $this->options;
147
+ }
148
+
149
+
150
+ /**
151
+ * Get an option.
152
+ *
153
+ * @since 2.4
154
+ *
155
+ * @param (string) $option_name Name of the option.
156
+ *
157
+ * @return (mixed) Return null if the option dosn't exist.
158
+ */
159
+ public function get_option( $option_name ) {
160
+ $options = $this->get_options();
161
+ return $option_name && isset( $options[ $option_name ] ) ? $options[ $option_name ] : null;
162
+ }
163
+
164
+
165
+ /**
166
+ * Get the slugs.
167
+ *
168
+ * @return (array)
169
+ */
170
+ public function get_slugs() {
171
+ $this->maybe_clear_options_cache();
172
+
173
+ if ( ! isset( $this->slugs ) ) {
174
+ $this->slugs = static::get_sub_options( 'slugs', $this->get_options() );
175
+ }
176
+
177
+ return $this->slugs;
178
+ }
179
+
180
+
181
+ /**
182
+ * Setting field labels for the slugs.
183
+ *
184
+ * @return (array)
185
+ */
186
+ public function get_slug_field_labels() {
187
+ $this->maybe_clear_options_cache();
188
+
189
+ if ( isset( $this->labels ) ) {
190
+ return $this->labels;
191
+ }
192
+
193
+ $this->labels = array(
194
+ 'login' => __( 'Log in' ),
195
+ 'logout' => __( 'Log out' ),
196
+ 'register' => __( 'Register' ),
197
+ 'lostpassword' => __( 'Lost Password' ),
198
+ 'resetpass' => __( 'Password Reset' ),
199
+ );
200
+
201
+ $new_actions = static::get_additional_labels();
202
+
203
+ if ( $new_actions ) {
204
+ $new_actions = array_diff_key( $new_actions, $this->labels );
205
+ $this->labels = array_merge( $this->labels, $new_actions );
206
+ }
207
+
208
+ return $this->labels;
209
+ }
210
+
211
+
212
+ /**
213
+ * Return the "other" original login actions: not the ones listed in our settings.
214
+ *
215
+ * @return (array)
216
+ */
217
+ public function get_other_actions() {
218
+ return array_diff_key( array(
219
+ 'retrievepassword' => 'retrievepassword',
220
+ 'rp' => 'rp',
221
+ ), $this->get_slug_field_labels() );
222
+ }
223
+
224
+
225
+ /**
226
+ * Clear options cache.
227
+ *
228
+ * @param (bool) $force Clear the cache manually.
229
+ */
230
+ public function maybe_clear_options_cache( $force = false ) {
231
+ $clear = false;
232
+ /**
233
+ * Clear options cache.
234
+ *
235
+ * @param (bool) $clear Return true if you want to clear the cache.
236
+ */
237
+ if ( $force || apply_filters( static::OPTION_NAME . '_clear_options_cache', $clear ) ) {
238
+ $this->options = null;
239
+ $this->options_default = null;
240
+ $this->slugs = null;
241
+ $this->labels = null;
242
+ remove_all_filters( static::OPTION_NAME . '_clear_options_cache' );
243
+ }
244
+ }
245
+
246
+
247
+ /**
248
+ * An improved version of `register_setting()`, that always exists and that works for network options.
249
+ */
250
+ protected function register_setting() {
251
+ global $new_whitelist_options;
252
+
253
+ $sanitize_callback = array( $this, 'sanitize_options' );
254
+
255
+ if ( ! is_multisite() ) {
256
+ if ( function_exists( 'register_setting' ) ) {
257
+ register_setting( static::OPTION_GROUP, static::OPTION_NAME, $sanitize_callback );
258
+ return;
259
+ }
260
+
261
+ $new_whitelist_options = isset( $new_whitelist_options ) && is_array( $new_whitelist_options ) ? $new_whitelist_options : array(); // WPCS: override ok.
262
+ $new_whitelist_options[ static::OPTION_GROUP ] = isset( $new_whitelist_options[ static::OPTION_GROUP ] ) && is_array( $new_whitelist_options[ static::OPTION_GROUP ] ) ? $new_whitelist_options[ static::OPTION_GROUP ] : array();
263
+ $new_whitelist_options[ static::OPTION_GROUP ][] = static::OPTION_NAME;
264
+ } elseif ( is_admin() ) {
265
+ $whitelist = sfml_cache_data( 'new_whitelist_network_options' );
266
+ $whitelist = is_array( $whitelist ) ? $whitelist : array();
267
+ $whitelist[ static::OPTION_GROUP ] = isset( $whitelist[ static::OPTION_GROUP ] ) ? $whitelist[ static::OPTION_GROUP ] : array();
268
+ $whitelist[ static::OPTION_GROUP ][] = static::OPTION_NAME;
269
+ sfml_cache_data( 'new_whitelist_network_options', $whitelist );
270
+ }
271
+
272
+ if ( $sanitize_callback ) {
273
+ add_filter( 'sanitize_option_' . static::OPTION_NAME, $sanitize_callback );
274
+ }
275
+ }
276
+
277
+
278
+ /**
279
+ * Sanitize options on save.
280
+ *
281
+ * @param (array) $options Options to sanitize.
282
+ *
283
+ * @return (array)
284
+ */
285
+ public function sanitize_options( $options = array() ) {
286
+ $errors = array( 'forbidden' => array(), 'duplicates' => array() );
287
+ $old_options = get_site_option( static::OPTION_NAME );
288
+ $default_options = $this->get_default_options();
289
+ $sanitized_options = array();
290
+
291
+ // Add and sanitize slugs.
292
+ $default_slugs = static::get_sub_options( 'slugs', $default_options );
293
+ $exclude = $this->get_other_actions();
294
+
295
+ foreach ( $default_slugs as $slug_key => $default_slug ) {
296
+
297
+ if ( isset( $exclude[ $slug_key ] ) ) {
298
+ $sanitized_options[ 'slugs.' . $slug_key ] = $exclude[ $slug_key ];
299
+ continue;
300
+ }
301
+
302
+ $sanitized_options[ 'slugs.' . $slug_key ] = false;
303
+
304
+ if ( ! empty( $options[ 'slugs.' . $slug_key ] ) ) {
305
+ $tmp_slug = sanitize_title( $options[ 'slugs.' . $slug_key ], $default_slug );
306
+
307
+ // 'postpass', 'retrievepassword' and 'rp' are forbidden.
308
+ if ( in_array( $tmp_slug, $exclude, true ) ) {
309
+ $errors['forbidden'][] = $tmp_slug;
310
+ }
311
+ // Make sure the slug is not already set for another action.
312
+ elseif ( in_array( $tmp_slug, $sanitized_options, true ) ) {
313
+ $errors['duplicates'][] = $tmp_slug;
314
+ }
315
+ // Yay!
316
+ else {
317
+ $sanitized_options[ 'slugs.' . $slug_key ] = $tmp_slug;
318
+ }
319
+ }
320
+
321
+ // Fallback to old value or default value.
322
+ if ( ! $sanitized_options[ 'slugs.' . $slug_key ] ) {
323
+ if ( ! isset( $exclude[ $slug_key ] ) && ! empty( $old_options[ 'slugs.' . $slug_key ] ) ) {
324
+ $sanitized_options[ 'slugs.' . $slug_key ] = sanitize_title( $old_options[ 'slugs.' . $slug_key ], $default_slug );
325
+ } else {
326
+ $sanitized_options[ 'slugs.' . $slug_key ] = $default_slug;
327
+ }
328
+ }
329
+ }
330
+
331
+ // Add and sanitize other options.
332
+ if ( isset( $default_options['deny_wp_login_access'] ) ) {
333
+ if ( isset( $options['deny_wp_login_access'] ) ) {
334
+
335
+ $sanitized_options['deny_wp_login_access'] = min( 3, max( 1, (int) $options['deny_wp_login_access'] ) );
336
+
337
+ } elseif ( isset( $old_options['deny_wp_login_access'] ) ) {
338
+
339
+ $sanitized_options['deny_wp_login_access'] = min( 3, max( 1, (int) $old_options['deny_wp_login_access'] ) );
340
+
341
+ } else {
342
+ $sanitized_options['deny_wp_login_access'] = $default_options['deny_wp_login_access'];
343
+ }
344
+ }
345
+
346
+ if ( isset( $default_options['deny_admin_access'] ) ) {
347
+ if ( isset( $options['deny_admin_access'] ) ) {
348
+
349
+ $sanitized_options['deny_admin_access'] = min( 3, max( 0, (int) $options['deny_admin_access'] ) );
350
+
351
+ } elseif ( isset( $old_options['deny_admin_access'] ) ) {
352
+
353
+ $sanitized_options['deny_admin_access'] = min( 3, max( 0, (int) $old_options['deny_admin_access'] ) );
354
+
355
+ } else {
356
+ $sanitized_options['deny_admin_access'] = $default_options['deny_admin_access'];
357
+ }
358
+ }
359
+
360
+ /**
361
+ * Filter the options after being sanitized.
362
+ *
363
+ * @param (array) $sanitized_options The new options, sanitized.
364
+ * @param (array) $options The submitted options.
365
+ */
366
+ $options_tmp = apply_filters( 'sfml_sanitize_options', $sanitized_options, $options );
367
+ // Make sure no keys have been removed.
368
+ $sanitized_options = array_merge( $sanitized_options, $options_tmp );
369
+
370
+ // Clear options cache.
371
+ $this->maybe_clear_options_cache( true );
372
+
373
+ // Add the rewrite rules to the `.htaccess`/`web.config` file.
374
+ $old_slugs = static::get_sub_options( 'slugs', $old_options );
375
+ $new_slugs = static::get_sub_options( 'slugs', $sanitized_options );
376
+
377
+ if ( $old_slugs !== $new_slugs ) {
378
+ sfml_include_rewrite_file();
379
+ sfml_write_rules( sfml_rules( $new_slugs ) );
380
+ }
381
+
382
+ // Trigger errors.
383
+ if ( is_admin() ) {
384
+ $errors['forbidden'] = array_unique( $errors['forbidden'] );
385
+ $errors['duplicates'] = array_unique( $errors['duplicates'] );
386
+
387
+ if ( $nbr_forbidden = count( $errors['forbidden'] ) ) {
388
+ /** Translators: %s is an URL slug name. */
389
+ add_settings_error( 'sfml_settings', 'forbidden-slugs', sprintf( _n( 'The slug %s is forbidden.', 'The slugs %s are forbidden.', $nbr_forbidden, 'sf-move-login' ), wp_sprintf( '<code>%l</code>', $errors['forbidden'] ) ) );
390
+ }
391
+ if ( ! empty( $errors['duplicates'] ) ) {
392
+ add_settings_error( 'sfml_settings', 'duplicates-slugs', __( 'The links can\'t have the same slugs.', 'sf-move-login' ) );
393
+ }
394
+ }
395
+
396
+ return $sanitized_options;
397
+ }
398
+
399
+
400
+ /**
401
+ * Get sub-options.
402
+ *
403
+ * For example:
404
+ * static::get_sub_options( 'foo', array(
405
+ * 'option1' => 'value1',
406
+ * 'foo.option2' => 'value2',
407
+ * 'foo.option3' => 'value3',
408
+ * ) );
409
+ * Will return:
410
+ * array(
411
+ * 'option2' => 'value2',
412
+ * 'option3' => 'value3',
413
+ * )
414
+ *
415
+ * @param (string) $name The sub-option name.
416
+ * @param (array) $options Array of options.
417
+ *
418
+ * @return (array)
419
+ */
420
+ public static function get_sub_options( $name, $options ) {
421
+ if ( ! $options || ! $name ) {
422
+ return array();
423
+ }
424
+
425
+ $options = (array) $options;
426
+
427
+ if ( isset( $options[ $name ] ) ) {
428
+ return $options[ $name ];
429
+ }
430
+
431
+ $group = array();
432
+ $name = rtrim( $name, '.' ) . '.';
433
+
434
+ foreach ( $options as $k => $v ) {
435
+ if ( 0 === strpos( $k, $name ) ) {
436
+ $group[ substr( $k, strlen( $name ) ) ] = $v;
437
+ }
438
+ }
439
+
440
+ return ! empty( $group ) ? $group : null;
441
+ }
442
+
443
+
444
+ /**
445
+ * Get custom labels (added by other plugins).
446
+ *
447
+ * @since 2.4
448
+ *
449
+ * @return (array)
450
+ */
451
+ public static function get_additional_labels() {
452
+ $new_actions = array();
453
+ /**
454
+ * Plugins can add their own actions.
455
+ *
456
+ * @param (array) $new_actions Custom actions.
457
+ */
458
+ return apply_filters( 'sfml_additional_slugs', $new_actions );
459
+ }
460
+ }
inc/classes/class-sfml-singleton.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' );
3
+
4
+ /**
5
+ * Singleton class.
6
+ *
7
+ * @package Move Login
8
+ * @since 2.4
9
+ */
10
+ class SFML_Singleton {
11
+
12
+ const VERSION = '1.0';
13
+
14
+ /**
15
+ * Sub-classes must declare a Singleton property as follow:
16
+ *
17
+ * The reference to *Singleton* instance of this class.
18
+ *
19
+ * @var (object)
20
+ */
21
+ protected static $_instance;
22
+
23
+
24
+ /**
25
+ * Init.
26
+ * Sub-classes may extend this method.
27
+ *
28
+ * @since 1.0
29
+ */
30
+ protected function _init() {}
31
+
32
+
33
+ /**
34
+ * Get the *Singleton* instance of this class.
35
+ *
36
+ * @since 1.0
37
+ *
38
+ * @return (object) The *Singleton* instance.
39
+ */
40
+ final public static function get_instance() {
41
+ if ( ! isset( static::$_instance ) ) {
42
+ static::$_instance = new static;
43
+ }
44
+
45
+ return static::$_instance;
46
+ }
47
+
48
+
49
+ /**
50
+ * Private constructor to prevent creating a new instance of the *Singleton* via the `new` operator from outside of this class.
51
+ *
52
+ * @since 1.0
53
+ */
54
+ final private function __construct() {
55
+ $this->_init();
56
+ }
57
+
58
+
59
+ /**
60
+ * Private clone method to prevent cloning of the instance of the *Singleton* instance.
61
+ *
62
+ * @since 1.0
63
+ */
64
+ final private function __clone() {}
65
+
66
+
67
+ /**
68
+ * Private unserialize method to prevent unserializing of the *Singleton* instance.
69
+ *
70
+ * @since 1.0
71
+ */
72
+ final private function __wakeup() {}
73
+ }
inc/functions/compat.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ if ( ! function_exists( 'set_url_scheme' ) ) :
7
+ /**
8
+ * Sets the scheme for a URL.
9
+ *
10
+ * @since WP 3.4.0
11
+ * @since WP 4.4.0 The 'rest' scheme was added.
12
+ *
13
+ * @param (string) $url Absolute URL that includes a scheme.
14
+ * @param (string|null) $scheme Optional. Scheme to give $url. Currently 'http', 'https', 'login',
15
+ * 'login_post', 'admin', 'relative', 'rest', 'rpc', or null. Default null.
16
+ * @return (string) $url URL with chosen scheme.
17
+ */
18
+ function set_url_scheme( $url, $scheme = null ) {
19
+ $orig_scheme = $scheme;
20
+
21
+ if ( ! $scheme ) {
22
+ $scheme = is_ssl() ? 'https' : 'http';
23
+ } elseif ( 'admin' === $scheme || 'login' === $scheme || 'login_post' === $scheme || 'rpc' === $scheme ) {
24
+ $scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http';
25
+ } elseif ( 'http' !== $scheme && 'https' !== $scheme && 'relative' !== $scheme ) {
26
+ $scheme = is_ssl() ? 'https' : 'http';
27
+ }
28
+
29
+ $url = trim( $url );
30
+
31
+ if ( substr( $url, 0, 2 ) === '//' ) {
32
+ $url = 'http:' . $url;
33
+ }
34
+
35
+ if ( 'relative' === $scheme ) {
36
+ $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) );
37
+
38
+ if ( '' !== $url && '/' === $url[0] ) {
39
+ $url = '/' . ltrim( $url , "/ \t\n\r\0\x0B" );
40
+ }
41
+ } else {
42
+ $url = preg_replace( '#^\w+://#', $scheme . '://', $url );
43
+ }
44
+
45
+ /**
46
+ * Filters the resulting URL after setting the scheme.
47
+ *
48
+ * @since WP 3.4.0
49
+ *
50
+ * @param (string) $url The complete URL including scheme and path.
51
+ * @param (string) $scheme Scheme applied to the URL. One of 'http', 'https', or 'relative'.
52
+ * @param (string|null) $orig_scheme Scheme requested for the URL. One of 'http', 'https', 'login',
53
+ * 'login_post', 'admin', 'relative', 'rest', 'rpc', or null.
54
+ */
55
+ return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );
56
+ }
57
+ endif;
58
+
59
+
60
+ if ( ! function_exists( 'wp_is_writable' ) ) :
61
+ /**
62
+ * Determine if a directory is writable.
63
+ *
64
+ * This function is used to work around certain ACL issues in PHP primarily affecting Windows Servers.
65
+ *
66
+ * @since WP 3.6.0
67
+ * @see win_is_writable()
68
+ *
69
+ * @param (string) $path Path to check for write-ability.
70
+ *
71
+ * @return (bool) Whether the path is writable.
72
+ */
73
+ function wp_is_writable( $path ) {
74
+ if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) {
75
+ return win_is_writable( $path );
76
+ }
77
+ return @is_writable( $path );
78
+ }
79
+ endif;
inc/functions/rewrite.php ADDED
@@ -0,0 +1,520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
7
+ /* !INCLUDES ==================================================================================== */
8
+ /*------------------------------------------------------------------------------------------------*/
9
+
10
+ require_once( ABSPATH . WPINC . '/functions.php' );
11
+ require_once( ABSPATH . 'wp-admin/includes/misc.php' );
12
+
13
+
14
+ /*------------------------------------------------------------------------------------------------*/
15
+ /* !REWRITE RULES =============================================================================== */
16
+ /*------------------------------------------------------------------------------------------------*/
17
+
18
+ /**
19
+ * Get generic rules for the rewrite rules, based on the settings.
20
+ *
21
+ * @param (array) $actions An array of action => slug.
22
+ *
23
+ * @return (array) An array with the rewritted URIs (slug) as keys and the real URIs as values.
24
+ */
25
+ function sfml_rules( $actions = null ) {
26
+ if ( ! $actions || ! is_array( $actions ) ) {
27
+ $actions = sfml_get_slugs();
28
+ }
29
+
30
+ $rules = array();
31
+
32
+ foreach ( $actions as $action => $slug ) {
33
+ $rules[ $slug ] = 'wp-login.php' . ( 'login' === $action ? '' : '?action=' . $action );
34
+ }
35
+
36
+ return $rules;
37
+ }
38
+
39
+
40
+ /**
41
+ * Add rules into the `.htaccess` or `web.config` file.
42
+ *
43
+ * @param (array) $rules Generic rules to write.
44
+ *
45
+ * @return (bool) True on success, false if the file is not writable or upon failure.
46
+ */
47
+ function sfml_write_rules( $rules = null ) {
48
+ global $is_apache, $is_iis7;
49
+
50
+ $rules = isset( $rules ) ? $rules : sfml_rules();
51
+
52
+ // Nginx.
53
+ if ( sfml_is_nginx() ) {
54
+ $success = false;
55
+ }
56
+ // The file is not writable.
57
+ elseif ( ! sfml_can_write_file() ) {
58
+ $success = false;
59
+ }
60
+ // Apache.
61
+ elseif ( $is_apache ) {
62
+ $success = sfml_insert_apache_rewrite_rules( $rules );
63
+ }
64
+ // IIS.
65
+ elseif ( $is_iis7 ) {
66
+ $success = sfml_insert_iis7_rewrite_rules( $rules );
67
+ }
68
+ // Souldn't happen.
69
+ else {
70
+ $success = false;
71
+ }
72
+
73
+ /**
74
+ * Triggered each time the `.htaccess` or `web.config` file is edited (or not).
75
+ *
76
+ * @param (array) $rules Generic rules to write.
77
+ * @param (bool) $success Whether the rules have successfully added to the file or removed from the file.
78
+ */
79
+ do_action( 'sfml_write_rules', $rules, $success );
80
+
81
+ return $success;
82
+ }
83
+
84
+
85
+ /**
86
+ * Is WP a MultiSite and a subfolder install?
87
+ *
88
+ * @return (bool)
89
+ */
90
+ function sfml_is_subfolder_install() {
91
+ global $wpdb;
92
+ static $subfolder_install;
93
+
94
+ if ( ! isset( $subfolder_install ) ) {
95
+ if ( is_multisite() ) {
96
+ $subfolder_install = ! is_subdomain_install();
97
+ } elseif ( ! is_null( $wpdb->sitemeta ) ) {
98
+ $subfolder_install = ! $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
99
+ } else {
100
+ $subfolder_install = false;
101
+ }
102
+ }
103
+
104
+ return $subfolder_install;
105
+ }
106
+
107
+
108
+ /**
109
+ * Get infos for the rewrite rules.
110
+ * The main concern is about directories.
111
+ *
112
+ * @return (array) An array containing the following keys:
113
+ * 'base' => Rewrite base, or "home directory".
114
+ * 'wp_dir' => WP directory.
115
+ * 'site_dir' => Directory containing the WordPress files.
116
+ * 'is_sub' => Is it a subfolder install? (Multisite).
117
+ * 'site_from' => Regex for first part of the rewrite rule (WP files).
118
+ * 'site_to' => First part of the rewrited address (WP files).
119
+ * In case of MultiSite with sub-folders, this is not really where the files are: WP rewrites the admin URL for example, which is based on the "site URL".
120
+ * 'home_from' => Regex for first part of the rewrite rule (home URL).
121
+ * 'home_to' => First part of the rewrited address (home URL).
122
+ */
123
+ function sfml_get_rewrite_bases() {
124
+ global $is_apache, $is_nginx, $is_iis7;
125
+ static $bases;
126
+
127
+ if ( isset( $bases ) ) {
128
+ return $bases;
129
+ }
130
+
131
+ $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
132
+ $wp_dir = sfml_get_wp_directory(); // WP in its own directory.
133
+ $is_sub = sfml_is_subfolder_install(); // MultiSite by sub-folders.
134
+ $site_dir = $base . ltrim( $wp_dir, '/' );
135
+
136
+ $bases = array(
137
+ 'base' => $base, // '/' or '/sub-dir/'.
138
+ 'wp_dir' => $wp_dir, // '' or '/wp-dir/'.
139
+ 'site_dir' => $site_dir, // '/', '/wp-dir/', '/sub-dir/', or '/sub-dir/wp-dir/'.
140
+ 'is_sub' => $is_sub, // True or false.
141
+ );
142
+
143
+ // Apache.
144
+ if ( $is_apache ) {
145
+ /**
146
+ * In the `*_from` fields, we don't add `$base` because we use `RewriteBase $base` in the rewrite rules.
147
+ * In the `*_to` fields, `$base` is optional, but WP adds it so we do the same for concistancy.
148
+ */
149
+ if ( $is_sub ) {
150
+ // MultiSite by sub-folders.
151
+ return ( $bases = array_merge( $bases, array(
152
+ // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog.
153
+ 'site_from' => $wp_dir ? '([_0-9a-zA-Z-]+/)' : '(([_0-9a-zA-Z-]+/)?)',
154
+ 'site_to' => $base . '$1',
155
+ 'home_from' => '([_0-9a-zA-Z-]+/)?',
156
+ 'home_to' => $base . '$1',
157
+ ) ) );
158
+ } else {
159
+ // Not MultiSite, or MultiSite by sub-domains.
160
+ return ( $bases = array_merge( $bases, array(
161
+ 'site_from' => $wp_dir,
162
+ 'site_to' => $site_dir,
163
+ 'home_from' => '',
164
+ 'home_to' => $base,
165
+ ) ) );
166
+ }
167
+ }
168
+
169
+ // Nginx.
170
+ if ( $is_nginx ) {
171
+ if ( $is_sub ) {
172
+ // MultiSite by sub-folders.
173
+ return ( $bases = array_merge( $bases, array(
174
+ // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog.
175
+ 'site_from' => $base . '(' . ( $wp_dir ? '[_0-9a-zA-Z-]+/' : '([_0-9a-zA-Z-]+/)?' ) . ')',
176
+ 'site_to' => $base . '$1',
177
+ 'home_from' => $base . '([_0-9a-zA-Z-]+/)?',
178
+ 'home_to' => $base . '$1',
179
+ ) ) );
180
+ } else {
181
+ // Not MultiSite, or MultiSite by sub-domains.
182
+ return ( $bases = array_merge( $bases, array(
183
+ 'site_from' => $site_dir,
184
+ 'site_to' => $site_dir,
185
+ 'home_from' => $base,
186
+ 'home_to' => $base,
187
+ ) ) );
188
+ }
189
+ }
190
+
191
+ // IIS7.
192
+ if ( $is_iis7 ) {
193
+ $base = ltrim( $base, '/' ); // No heading slash for IIS: '' or 'sub-dir/'.
194
+ $site_dir = ltrim( $site_dir, '/' ); // No heading slash for IIS: '', 'wp-dir/', 'sub-dir/', or 'sub-dir/wp-dir/'.
195
+
196
+ if ( $is_sub ) {
197
+ // MultiSite by sub-folders.
198
+ return ( $bases = array_merge( $bases, array(
199
+ 'base' => $base,
200
+ 'site_dir' => $site_dir,
201
+ // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog.
202
+ 'site_from' => $base . '(' . ( $wp_dir ? '[_0-9a-zA-Z-]+/' : '([_0-9a-zA-Z-]+/)?' ) . ')',
203
+ 'site_to' => $base . '{R:1}',
204
+ 'home_from' => $base . '([_0-9a-zA-Z-]+/)?',
205
+ 'home_to' => $base . '{R:1}',
206
+ ) ) );
207
+ } else {
208
+ // Not MultiSite, or MultiSite by sub-domains.
209
+ return ( $bases = array_merge( $bases, array(
210
+ 'base' => $base,
211
+ 'site_dir' => $site_dir,
212
+ 'site_from' => $site_dir,
213
+ 'site_to' => $site_dir,
214
+ 'home_from' => $base,
215
+ 'home_to' => $base,
216
+ ) ) );
217
+ }
218
+ }
219
+
220
+ return ( $bases = false );
221
+ }
222
+
223
+
224
+ /*------------------------------------------------------------------------------------------------*/
225
+ /* !NGINX ======================================================================================= */
226
+ /*------------------------------------------------------------------------------------------------*/
227
+
228
+ /**
229
+ * Get the rewrite rules for Nginx that should be added into the `nginx.conf` file.
230
+ *
231
+ * @param (array) $rules Generic rules to write.
232
+ *
233
+ * @return (array) The rewrite rules.
234
+ */
235
+ function sfml_nginx_rewrite_rules( $rules = array() ) {
236
+ if ( ! $rules || ! is_array( $rules ) ) {
237
+ return array();
238
+ }
239
+
240
+ $bases = sfml_get_rewrite_bases();
241
+ $out = array();
242
+
243
+ foreach ( $rules as $slug => $rule ) {
244
+ $out[] = 'rewrite ^' . $bases['site_from'] . $slug . '/?$ ' . $bases['site_dir'] . $rule . ' last;';
245
+ }
246
+
247
+ return $out;
248
+ }
249
+
250
+
251
+ /*------------------------------------------------------------------------------------------------*/
252
+ /* !APACHE ====================================================================================== */
253
+ /*------------------------------------------------------------------------------------------------*/
254
+
255
+ /**
256
+ * Get the rewrite rules for Apache that should be added into the `.htaccess` file.
257
+ *
258
+ * @param (array) $rules Generic rules to write.
259
+ *
260
+ * @return (array) The rewrite rules.
261
+ */
262
+ function sfml_apache_rewrite_rules( $rules = array() ) {
263
+ if ( ! $rules || ! is_array( $rules ) ) {
264
+ return array();
265
+ }
266
+
267
+ $bases = sfml_get_rewrite_bases();
268
+ $out = array(
269
+ '<IfModule mod_rewrite.c>',
270
+ ' RewriteEngine On',
271
+ ' RewriteBase ' . $bases['base'],
272
+ );
273
+
274
+ foreach ( $rules as $slug => $rule ) {
275
+ $out[] = ' RewriteRule ^' . $bases['site_from'] . $slug . '/?$ ' . $bases['site_dir'] . $rule . ' [QSA,L]';
276
+ }
277
+
278
+ $out[] = '</IfModule>';
279
+
280
+ return $out;
281
+ }
282
+
283
+
284
+ /**
285
+ * Add or remove rules into the `.htaccess` file.
286
+ *
287
+ * @param (array) $rules Generic rules to write.
288
+ *
289
+ * @return (bool) True on success, false on failure.
290
+ */
291
+ function sfml_insert_apache_rewrite_rules( $rules = array() ) {
292
+ if ( $rules ) {
293
+ $rules = sfml_apache_rewrite_rules( $rules );
294
+ $rules = implode( "\n", $rules );
295
+ $rules = trim( $rules );
296
+ } else {
297
+ $rules = '';
298
+ }
299
+
300
+ $htaccess_file = sfml_get_home_path() . '.htaccess';
301
+ $has_htaccess = file_exists( $htaccess_file );
302
+
303
+ if ( ! $rules ) {
304
+ // We want to remove the rules.
305
+ if ( ! $has_htaccess ) {
306
+ // The file does not exist (uh?). All good.
307
+ return true;
308
+ }
309
+
310
+ $htaccess_is_writable = $has_htaccess && wp_is_writable( $htaccess_file );
311
+
312
+ if ( ! $htaccess_is_writable ) {
313
+ // The file is not writable.
314
+ return false;
315
+ }
316
+ // No need to test for mod rewrite, we want to remove rules.
317
+ } elseif ( ! sfml_can_write_file() ) {
318
+ // We can't add rules.
319
+ return false;
320
+ }
321
+
322
+ $marker = 'SF Move Login';
323
+ // Current htaccess content.
324
+ $content = $has_htaccess ? file_get_contents( $htaccess_file ) : '';
325
+ // Remove the SF Move Login marker.
326
+ $content = preg_replace( "/# BEGIN $marker.*# END $marker\n*/is", '', $content );
327
+
328
+ // The new content is inserted at the begining of the file.
329
+ if ( $rules ) {
330
+ $content = "# BEGIN $marker\n$rules\n# END $marker\n\n\n$content";
331
+ }
332
+
333
+ // Update the `.htaccess` file.
334
+ return (bool) file_put_contents( $htaccess_file , $content );
335
+ }
336
+
337
+
338
+ /*------------------------------------------------------------------------------------------------*/
339
+ /* !IIS ========================================================================================= */
340
+ /*------------------------------------------------------------------------------------------------*/
341
+
342
+ /**
343
+ * Get the rewrite rules for IIS that should be added into the `web.config` file.
344
+ *
345
+ * @param (array) $rules Generic rules to write.
346
+ *
347
+ * @return (array) The rewrite rules.
348
+ */
349
+ function sfml_iis7_rewrite_rules( $rules = array() ) {
350
+ if ( ! $rules || ! is_array( $rules ) ) {
351
+ return array();
352
+ }
353
+
354
+ $bases = sfml_get_rewrite_bases();
355
+ $rule_i = 1;
356
+ $space = str_repeat( ' ', 8 );
357
+ $out = array();
358
+
359
+ foreach ( $rules as $slug => $rule ) {
360
+ $out[] = $space . '<rule name="SF Move Login Rule ' . $rule_i . '" stopProcessing="true">' . "\n"
361
+ . $space . ' <match url="^' . $bases['site_from'] . $slug . '/?$" ignoreCase="false" />' . "\n"
362
+ . $space . ' <action type="Redirect" url="' . $bases['site_dir'] . $rule . '" redirectType="Permanent" />' . "\n"
363
+ . $space . '</rule>';
364
+ $rule_i++;
365
+ }
366
+
367
+ return $out;
368
+ }
369
+
370
+
371
+ /**
372
+ * Add or remove rules into the `web.config` file.
373
+ *
374
+ * @param (array) $rules Generic rules to write.
375
+ *
376
+ * @return (bool) True on success, false on failure.
377
+ */
378
+ function sfml_insert_iis7_rewrite_rules( $rules = array() ) {
379
+ if ( ! class_exists( 'DOMDocument' ) ) {
380
+ return false;
381
+ }
382
+
383
+ if ( $rules ) {
384
+ $rules = sfml_iis7_rewrite_rules( $rules );
385
+ $rules = implode( "\n", $rules );
386
+ $rules = trim( $rules );
387
+ } else {
388
+ $rules = '';
389
+ }
390
+
391
+ $web_config_file = sfml_get_home_path() . 'web.config';
392
+ $has_web_config = file_exists( $web_config_file );
393
+
394
+ if ( ! $rules ) {
395
+ // We want to remove the rules.
396
+ if ( ! $has_web_config ) {
397
+ // The file does not exist (uh?). All good.
398
+ return true;
399
+ }
400
+
401
+ $web_config_is_writable = $has_web_config && wp_is_writable( $web_config_file );
402
+
403
+ if ( ! $web_config_is_writable ) {
404
+ // The file is not writable.
405
+ return false;
406
+ }
407
+ // No need to test for permalinks support, we want to remove rules.
408
+ } elseif ( ! sfml_can_write_file() ) {
409
+ // We can't add rules.
410
+ return false;
411
+ }
412
+
413
+ // If configuration file does not exist then we create one.
414
+ if ( ! $has_web_config ) {
415
+ $fp = fopen( $web_config_file, 'w' );
416
+ fwrite( $fp, '<configuration/>' );
417
+ fclose( $fp );
418
+ }
419
+
420
+ $doc = new DOMDocument();
421
+ $doc->preserveWhiteSpace = false;
422
+
423
+ if ( false === $doc->load( $web_config_file ) ) {
424
+ return false;
425
+ }
426
+
427
+ $marker = 'SF Move Login';
428
+ $xpath = new DOMXPath( $doc );
429
+ $path = '/configuration/system.webServer/rewrite/rules';
430
+
431
+ // Remove old rules.
432
+ $old_rules = $xpath->query( "$path/*[starts-with(@name,'$marker')]" );
433
+
434
+ if ( $old_rules->length > 0 ) {
435
+ foreach ( $old_nodes as $old_node ) {
436
+ $old_node->parentNode->removeChild( $old_node );
437
+ }
438
+ }
439
+
440
+ // No new rules?
441
+ if ( ! $rules ) {
442
+ $doc->formatOutput = true;
443
+ saveDomDocument( $doc, $web_config_file );
444
+ return true;
445
+ }
446
+
447
+ // Indentation.
448
+ $spaces = explode( '/', trim( $path, '/' ) );
449
+ $spaces = count( $spaces ) - 1;
450
+ $spaces = str_repeat( ' ', $spaces * 2 );
451
+
452
+ // Create fragment.
453
+ $fragment = $doc->createDocumentFragment();
454
+ $fragment->appendXML( "\n$spaces $rules" );
455
+
456
+ // Maybe create child nodes and then, prepend new nodes.
457
+ sfml_get_iis7_node( $doc, $xpath, $path, $fragment );
458
+
459
+ // Save and finish.
460
+ $doc->encoding = 'UTF-8';
461
+ $doc->formatOutput = true;
462
+ saveDomDocument( $doc, $web_config_file );
463
+
464
+ return true;
465
+ }
466
+
467
+
468
+ /**
469
+ * Get a DOMNode node.
470
+ * If it does not exist it is created recursively.
471
+ *
472
+ * @param (object) $doc DOMDocument element.
473
+ * @param (object) $xpath DOMXPath element.
474
+ * @param (string) $path Path to the desired node.
475
+ * @param (object) $child DOMNode to be prepended.
476
+ *
477
+ * @return (object) The DOMNode node.
478
+ */
479
+ function sfml_get_iis7_node( $doc, $xpath, $path, $child ) {
480
+ $nodelist = $xpath->query( $path );
481
+
482
+ if ( $nodelist->length > 0 ) {
483
+ return sfml_prepend_iis7_node( $nodelist->item( 0 ), $child );
484
+ }
485
+
486
+ $path = explode( '/', $path );
487
+ $node = array_pop( $path );
488
+ $path = implode( '/', $path );
489
+
490
+ $final_node = $doc->createElement( $node );
491
+
492
+ if ( $child ) {
493
+ $final_node->appendChild( $child );
494
+ }
495
+
496
+ return sfml_get_iis7_node( $doc, $xpath, $path, $final_node );
497
+ }
498
+
499
+
500
+ /**
501
+ * A shorthand to prepend a DOMNode node.
502
+ *
503
+ * @param (object) $container_node DOMNode that will contain the new node.
504
+ * @param (object) $new_node DOMNode to be prepended.
505
+ *
506
+ * @return (object) DOMNode containing the new node.
507
+ */
508
+ function sfml_prepend_iis7_node( $container_node, $new_node ) {
509
+ if ( ! $new_node ) {
510
+ return $container_node;
511
+ }
512
+
513
+ if ( $container_node->hasChildNodes() ) {
514
+ $container_node->insertBefore( $new_node, $container_node->firstChild );
515
+ } else {
516
+ $container_node->appendChild( $new_node );
517
+ }
518
+
519
+ return $container_node;
520
+ }
inc/{settings-page.php → functions/settings-page.php} RENAMED
@@ -7,24 +7,25 @@ if ( ! defined( 'ABSPATH' ) ) {
7
  /* !SETTINGS PAGE =============================================================================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
- // !Add settings fields and sections.
11
-
 
12
  function sfml_settings_fields() {
13
- $labels = SFML_Options::slugs_fields_labels();
14
  $defaults = sfml_get_default_options();
15
  $options = sfml_get_options();
16
 
17
- // Sections
18
- add_settings_section( 'slugs', __( 'Links' ), false, SFML_Options::OPTION_PAGE );
19
  add_settings_section( 'access', __( 'Access', 'sf-move-login' ), false, SFML_Options::OPTION_PAGE );
20
 
21
- // Fields
22
  foreach ( $labels as $slug => $label ) {
23
  if ( ! isset( $options[ 'slugs.' . $slug ] ) ) {
24
  continue;
25
  }
26
 
27
- // Slugs
28
  add_settings_field(
29
  'slugs-' . $slug,
30
  $label,
@@ -86,19 +87,14 @@ function sfml_settings_fields() {
86
  );
87
  }
88
 
89
- sfml_settings_fields();
90
 
91
-
92
- /*
93
  * If the parent page is 'options-general.php', WP will automaticaly use settings_errors().
94
  * But the alerts will be displayed before the page title, and then some JS will move it after the title.
95
  * Under some circumstances (large page, slow browser), the "swap" won't happen fast enough, and the user will see it.
96
  * For the settings in the network admin, settings_errors() is not used at all.
97
  * So I prefer use my own settings_errors(), displayed AFTER the title.
98
  */
99
-
100
- add_action( 'all_admin_notices', 'sfml_shunt_options_settings_errors', PHP_INT_MAX );
101
-
102
  function sfml_shunt_options_settings_errors() {
103
  global $parent_file;
104
  // Prevent wp-admin/options-head.php to be included.
@@ -106,8 +102,9 @@ function sfml_shunt_options_settings_errors() {
106
  }
107
 
108
 
109
- // !The settings page
110
-
 
111
  function sfml_settings_page() {
112
  global $wp_version;
113
  ?>
@@ -141,14 +138,17 @@ function sfml_settings_page() {
141
  /* !SETTINGS FIELDS ============================================================================= */
142
  /*------------------------------------------------------------------------------------------------*/
143
 
144
- // !Text field
145
-
 
 
 
146
  function sfml_text_field( $args ) {
147
- $name = ! empty( $args['name'] ) ? esc_attr( $args['name'] ) : ( ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false );
148
- $id = ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false;
149
- $value = isset( $args['value'] ) ? esc_attr( $args['value'] ) : '';
150
- $default = isset( $args['default'] ) ? esc_attr( $args['default'] ) : null;
151
- $atts = ! empty( $args['attributes'] ) ? build_html_atts( $args['attributes'] ) : '';
152
 
153
  if ( ! $name ) {
154
  return;
@@ -162,14 +162,18 @@ function sfml_text_field( $args ) {
162
  $value
163
  );
164
 
165
- if ( ! is_null( $default ) ) {
 
166
  echo ' <span class="description">' . sprintf( _x( '(default: %s)', 'default value', 'sf-move-login' ), $default ) . '</span>';
167
  }
168
  }
169
 
170
 
171
- // !Radio field
172
-
 
 
 
173
  function sfml_radio_field( $args ) {
174
  $name = ! empty( $args['name'] ) ? esc_attr( $args['name'] ) : ( ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false );
175
  $id = ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : 'radio-' . $name;
@@ -201,54 +205,61 @@ function sfml_radio_field( $args ) {
201
  $i++;
202
  }
203
 
204
- if ( ! is_null( $default ) && isset( $values[ $default ] ) ) {
 
205
  echo '<span class="description">' . sprintf( _x( '(default: %s)', 'default value', 'sf-move-login' ), $values[ $default ] ) . '</span>';
206
  }
207
  }
208
 
209
 
210
- // !A textarea displaying the rewrite rules. Used with or without Noop.
211
-
 
212
  function sfml_rewrite_rules_textarea() {
213
  global $is_apache, $is_iis7;
214
 
215
- if ( ! function_exists( 'sfml_write_rules' ) ) {
216
- include( SFML_PLUGIN_DIR . 'inc/rewrite.php' );
217
- }
218
 
219
  $is_nginx = sfml_is_nginx();
220
  $rules = sfml_rules();
221
 
222
- // Message
223
  $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
224
  $document_root_fix = str_replace( '\\', '/', realpath( $_SERVER['DOCUMENT_ROOT'] ) );
225
  $abspath_fix = str_replace( '\\', '/', ABSPATH );
226
  $home_path = strpos( $abspath_fix, $document_root_fix ) === 0 ? $document_root_fix . $base : sfml_get_home_path();
227
 
228
- // IIS
229
  if ( $is_iis7 ) {
230
  $file = 'web.config';
231
- $file_content = implode( "\n", sfml_iis7_rewrite_rules( $rules, 'SF Move Login' ) );
232
 
233
  $height = 20;
234
  $content = sprintf(
 
235
  __( 'If the plugin fails to add the new rewrite rules to your %1$s file, add the following to your %1$s file in %2$s, replacing other %3$s rules if they exist, <strong>above</strong> the line reading %4$s:', 'sf-move-login' ),
236
- '<code>' . $file . '</code>', '<code>' . $home_path . '</code>', '<strong>Move Login</strong>', '<code>&lt;rule name="WordPress Rule 1" stopProcessing="true"&gt;</code>'
 
 
 
237
  );
238
  }
239
- // nginx
240
  elseif ( $is_nginx ) {
241
  $file = 'nginx.conf';
242
  $file_content = implode( "\n", sfml_nginx_rewrite_rules( $rules ) );
243
 
244
  $height = substr_count( $file_content, "\n" );
245
- $content = sprintf(
246
- '<span style="color:red">' . __( 'The plugin can\'t add the new rewrite rules to your %s file by itself, you will need to add them manually.', 'sf-move-login' ) . '</span>',
247
- '<code>' . $file . '</code>'
248
- );
249
- $file = false; // Don't check id the file is writable.
 
 
 
250
  }
251
- // Apache
252
  elseif ( $is_apache ) {
253
  $file = '.htaccess';
254
  $file_content = "\n# BEGIN SF Move Login\n";
@@ -257,8 +268,12 @@ function sfml_rewrite_rules_textarea() {
257
 
258
  $height = substr_count( $file_content, "\n" );
259
  $content = sprintf(
 
260
  __( 'If the plugin fails to add the new rewrite rules to your %1$s file, add the following to your %1$s file in %2$s, replacing other %3$s rules if they exist, <strong>above</strong> the line reading %4$s:', 'sf-move-login' ),
261
- '<code>' . $file . '</code>', '<code>' . $home_path . '</code>', '<strong>Move Login</strong>', '<code># BEGIN WordPress</code>'
 
 
 
262
  );
263
  }
264
  // Not supported.
@@ -269,14 +284,16 @@ function sfml_rewrite_rules_textarea() {
269
  // Add a warning if the file is not writable.
270
  if ( $home_path && $file && ! wp_is_writable( $home_path . $file ) ) {
271
  $content .= '</p><p style="color:red">' . sprintf(
 
272
  __( 'Your %s file is not writable.', 'sf-move-login' ),
273
- '<code>' . $file . '</code>'
274
  );
275
  }
276
 
277
  // Add a warning if the plugin is bypassed.
278
  if ( defined( 'SFML_ALLOW_LOGIN_ACCESS' ) && SFML_ALLOW_LOGIN_ACCESS ) {
279
- $content .= '</p><p class="description">' . __( 'The constant <code>SFML_ALLOW_LOGIN_ACCESS</code> is defined to <code>true</code>, the settings below won\'t take effect.', 'sf-move-login' );
 
280
  }
281
 
282
  $content = '<p>' . $content . ' <button type="button" id="sfml-file-button" class="button-secondary hide-if-no-js" style="vertical-align:baseline">' . __( 'Show' ) . "</button></p>\n";
@@ -285,26 +302,3 @@ function sfml_rewrite_rules_textarea() {
285
 
286
  echo $content;
287
  }
288
-
289
-
290
- /*------------------------------------------------------------------------------------------------*/
291
- /* !TOOLS ======================================================================================= */
292
- /*------------------------------------------------------------------------------------------------*/
293
-
294
- // !Build a string for html attributes (means: separated by a space) : array( 'width' => '200', 'height' => '150', 'yolo' => 'foo' ) ==> ' width="200" height="150" yolo="foo"'
295
-
296
- if ( ! function_exists( 'build_html_atts' ) ) :
297
- function build_html_atts( $attributes, $quote = '"' ) {
298
- $out = '';
299
-
300
- if ( ! is_array( $attributes ) || empty( $attributes ) ) {
301
- return '';
302
- }
303
-
304
- foreach ( $attributes as $att_name => $att_value ) {
305
- $out .= ' ' . esc_attr( $att_name ) . '=' . $quote . esc_attr( $att_value ) . $quote;
306
- }
307
-
308
- return $out;
309
- }
310
- endif;
7
  /* !SETTINGS PAGE =============================================================================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
+ /**
11
+ * Add settings fields and sections.
12
+ */
13
  function sfml_settings_fields() {
14
+ $labels = SFML_Options::get_instance()->get_slug_field_labels();
15
  $defaults = sfml_get_default_options();
16
  $options = sfml_get_options();
17
 
18
+ // Sections.
19
+ add_settings_section( 'slugs', __( 'Choose your new URLs', 'sf-move-login' ), false, SFML_Options::OPTION_PAGE );
20
  add_settings_section( 'access', __( 'Access', 'sf-move-login' ), false, SFML_Options::OPTION_PAGE );
21
 
22
+ // Fields.
23
  foreach ( $labels as $slug => $label ) {
24
  if ( ! isset( $options[ 'slugs.' . $slug ] ) ) {
25
  continue;
26
  }
27
 
28
+ // Slugs.
29
  add_settings_field(
30
  'slugs-' . $slug,
31
  $label,
87
  );
88
  }
89
 
 
90
 
91
+ /**
 
92
  * If the parent page is 'options-general.php', WP will automaticaly use settings_errors().
93
  * But the alerts will be displayed before the page title, and then some JS will move it after the title.
94
  * Under some circumstances (large page, slow browser), the "swap" won't happen fast enough, and the user will see it.
95
  * For the settings in the network admin, settings_errors() is not used at all.
96
  * So I prefer use my own settings_errors(), displayed AFTER the title.
97
  */
 
 
 
98
  function sfml_shunt_options_settings_errors() {
99
  global $parent_file;
100
  // Prevent wp-admin/options-head.php to be included.
102
  }
103
 
104
 
105
+ /**
106
+ * The settings page
107
+ */
108
  function sfml_settings_page() {
109
  global $wp_version;
110
  ?>
138
  /* !SETTINGS FIELDS ============================================================================= */
139
  /*------------------------------------------------------------------------------------------------*/
140
 
141
+ /**
142
+ * Text field.
143
+ *
144
+ * @param (array) $args Arguments.
145
+ */
146
  function sfml_text_field( $args ) {
147
+ $name = ! empty( $args['name'] ) ? esc_attr( $args['name'] ) : ( ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false );
148
+ $id = ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false;
149
+ $value = isset( $args['value'] ) ? esc_attr( $args['value'] ) : '';
150
+ $default = isset( $args['default'] ) ? esc_attr( $args['default'] ) : null;
151
+ $atts = ! empty( $args['attributes'] ) ? sfml_build_html_atts( $args['attributes'] ) : '';
152
 
153
  if ( ! $name ) {
154
  return;
162
  $value
163
  );
164
 
165
+ if ( isset( $default ) ) {
166
+ /** Translators: %s is an option value. */
167
  echo ' <span class="description">' . sprintf( _x( '(default: %s)', 'default value', 'sf-move-login' ), $default ) . '</span>';
168
  }
169
  }
170
 
171
 
172
+ /**
173
+ * Radio field.
174
+ *
175
+ * @param (array) $args Arguments.
176
+ */
177
  function sfml_radio_field( $args ) {
178
  $name = ! empty( $args['name'] ) ? esc_attr( $args['name'] ) : ( ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : false );
179
  $id = ! empty( $args['label_for'] ) ? esc_attr( $args['label_for'] ) : 'radio-' . $name;
205
  $i++;
206
  }
207
 
208
+ if ( isset( $default ) && isset( $values[ $default ] ) ) {
209
+ /** Translators: %s is an option value. */
210
  echo '<span class="description">' . sprintf( _x( '(default: %s)', 'default value', 'sf-move-login' ), $values[ $default ] ) . '</span>';
211
  }
212
  }
213
 
214
 
215
+ /**
216
+ * A textarea displaying the rewrite rules.
217
+ */
218
  function sfml_rewrite_rules_textarea() {
219
  global $is_apache, $is_iis7;
220
 
221
+ sfml_include_rewrite_file();
 
 
222
 
223
  $is_nginx = sfml_is_nginx();
224
  $rules = sfml_rules();
225
 
226
+ // Message.
227
  $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
228
  $document_root_fix = str_replace( '\\', '/', realpath( $_SERVER['DOCUMENT_ROOT'] ) );
229
  $abspath_fix = str_replace( '\\', '/', ABSPATH );
230
  $home_path = strpos( $abspath_fix, $document_root_fix ) === 0 ? $document_root_fix . $base : sfml_get_home_path();
231
 
232
+ // IIS.
233
  if ( $is_iis7 ) {
234
  $file = 'web.config';
235
+ $file_content = implode( "\n", sfml_iis7_rewrite_rules( $rules ) );
236
 
237
  $height = 20;
238
  $content = sprintf(
239
+ /** Translators: 1 is a file name, 2 is a file path, 3 and 4 are small parts of code. */
240
  __( 'If the plugin fails to add the new rewrite rules to your %1$s file, add the following to your %1$s file in %2$s, replacing other %3$s rules if they exist, <strong>above</strong> the line reading %4$s:', 'sf-move-login' ),
241
+ "<code>$file</code>",
242
+ "<code>$home_path</code>",
243
+ '<strong>Move Login</strong>',
244
+ '<code>&lt;rule name="WordPress Rule 1" stopProcessing="true"&gt;</code>'
245
  );
246
  }
247
+ // Nginx.
248
  elseif ( $is_nginx ) {
249
  $file = 'nginx.conf';
250
  $file_content = implode( "\n", sfml_nginx_rewrite_rules( $rules ) );
251
 
252
  $height = substr_count( $file_content, "\n" );
253
+ $content = '<span style="color:red">' . sprintf(
254
+ /** Translators: 1 is a file name, 2 is a small part of code. */
255
+ __( 'The plugin can\'t add the new rewrite rules to your %1$s file by itself, you will need to add them manually inside the %2$s block.', 'sf-move-login' ),
256
+ "<code>$file</code>",
257
+ '<code>server</code>'
258
+ ) . '</span>';
259
+ // Don't check if the file is writable.
260
+ $file = false;
261
  }
262
+ // Apache.
263
  elseif ( $is_apache ) {
264
  $file = '.htaccess';
265
  $file_content = "\n# BEGIN SF Move Login\n";
268
 
269
  $height = substr_count( $file_content, "\n" );
270
  $content = sprintf(
271
+ /** Translators: 1 is a file name, 2 is a file path, 3 and 4 are small parts of code. */
272
  __( 'If the plugin fails to add the new rewrite rules to your %1$s file, add the following to your %1$s file in %2$s, replacing other %3$s rules if they exist, <strong>above</strong> the line reading %4$s:', 'sf-move-login' ),
273
+ "<code>$file</code>",
274
+ "<code>$home_path</code>",
275
+ '<strong>Move Login</strong>',
276
+ '<code># BEGIN WordPress</code>'
277
  );
278
  }
279
  // Not supported.
284
  // Add a warning if the file is not writable.
285
  if ( $home_path && $file && ! wp_is_writable( $home_path . $file ) ) {
286
  $content .= '</p><p style="color:red">' . sprintf(
287
+ /** Translators: %s is a file name. */
288
  __( 'Your %s file is not writable.', 'sf-move-login' ),
289
+ "<code>$file</code>"
290
  );
291
  }
292
 
293
  // Add a warning if the plugin is bypassed.
294
  if ( defined( 'SFML_ALLOW_LOGIN_ACCESS' ) && SFML_ALLOW_LOGIN_ACCESS ) {
295
+ /** Translators: 1 is a constant name, 2 is a constant value. */
296
+ $content .= '</p><p class="description">' . sprintf( __( 'The constant %1$s is defined to %2$s, the settings below won\'t take effect.', 'sf-move-login' ), '<code>SFML_ALLOW_LOGIN_ACCESS</code>', '<code>true</code>' );
297
  }
298
 
299
  $content = '<p>' . $content . ' <button type="button" id="sfml-file-button" class="button-secondary hide-if-no-js" style="vertical-align:baseline">' . __( 'Show' ) . "</button></p>\n";
302
 
303
  echo $content;
304
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/functions/utilities.php ADDED
@@ -0,0 +1,319 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
7
+ /* !OPTIONS ===================================================================================== */
8
+ /*------------------------------------------------------------------------------------------------*/
9
+
10
+ /**
11
+ * Get all options.
12
+ *
13
+ * @return (array) All plugin options.
14
+ */
15
+ function sfml_get_options() {
16
+ return SFML_Options::get_instance()->get_options();
17
+ }
18
+
19
+
20
+ /**
21
+ * Get default options.
22
+ *
23
+ * @return (array) Plugin default options.
24
+ */
25
+ function sfml_get_default_options() {
26
+ return SFML_Options::get_instance()->get_default_options();
27
+ }
28
+
29
+
30
+ /**
31
+ * Get the slugs.
32
+ *
33
+ * @return (array) All slugs.
34
+ */
35
+ function sfml_get_slugs() {
36
+ return SFML_Options::get_instance()->get_slugs();
37
+ }
38
+
39
+
40
+ /**
41
+ * Access to `wp-login.php`: what the user set.
42
+ *
43
+ * @return (int) 1: error message, 2: 404, 3: home.
44
+ */
45
+ function sfml_get_deny_wp_login_access() {
46
+ return SFML_Options::get_instance()->get_option( 'deny_wp_login_access' );
47
+ }
48
+
49
+
50
+ /**
51
+ * Access to the administration area: what the user set.
52
+ *
53
+ * @return (int) 0: nothing, 1: error message, 2: 404, 3: home.
54
+ */
55
+ function sfml_get_deny_admin_access() {
56
+ return SFML_Options::get_instance()->get_option( 'deny_admin_access' );
57
+ }
58
+
59
+
60
+ /*------------------------------------------------------------------------------------------------*/
61
+ /* !GENERIC TOOLS =============================================================================== */
62
+ /*------------------------------------------------------------------------------------------------*/
63
+
64
+ /**
65
+ * Store, get or delete static data.
66
+ * Getter: no need to provide a second parameter.
67
+ * Setter: provide a second parameter for the value.
68
+ * Deletter: provide null as second parameter to remove the previous value.
69
+ *
70
+ * @param (string) $key An identifier key.
71
+ *
72
+ * @return (mixed) The stored data or null.
73
+ */
74
+ function sfml_cache_data( $key ) {
75
+ static $data = array();
76
+
77
+ $func_get_args = func_get_args();
78
+
79
+ if ( array_key_exists( 1, $func_get_args ) ) {
80
+ if ( null === $func_get_args[1] ) {
81
+ unset( $data[ $key ] );
82
+ } else {
83
+ $data[ $key ] = $func_get_args[1];
84
+ }
85
+ }
86
+
87
+ return isset( $data[ $key ] ) ? $data[ $key ] : null;
88
+ }
89
+
90
+
91
+ /**
92
+ * Tell if the server runs Nginx.
93
+ *
94
+ * @return (bool) True if the server runs Nginx. False otherwize.
95
+ */
96
+ function sfml_is_nginx() {
97
+ global $is_nginx;
98
+
99
+ if ( is_null( $is_nginx ) ) {
100
+ $is_nginx = ! empty( $_SERVER['SERVER_SOFTWARE'] ) && strpos( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) !== false;
101
+ }
102
+
103
+ return $is_nginx;
104
+ }
105
+
106
+
107
+ /**
108
+ * Get the main blog ID.
109
+ *
110
+ * @return (int)
111
+ */
112
+ function sfml_get_main_blog_id() {
113
+ static $blog_id;
114
+
115
+ if ( isset( $blog_id ) ) {
116
+ return $blog_id;
117
+ }
118
+
119
+ if ( ! is_multisite() ) {
120
+ $blog_id = 1;
121
+ } elseif ( ! empty( $GLOBALS['current_site']->blog_id ) ) {
122
+ $blog_id = absint( $GLOBALS['current_site']->blog_id );
123
+ } elseif ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
124
+ $blog_id = absint( BLOG_ID_CURRENT_SITE );
125
+ } elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) {
126
+ // Deprecated.
127
+ $blog_id = absint( BLOGID_CURRENT_SITE );
128
+ }
129
+ $blog_id = ! empty( $blog_id ) ? $blog_id : 1;
130
+
131
+ return $blog_id;
132
+ }
133
+
134
+
135
+ /**
136
+ * Return the current URL.
137
+ *
138
+ * @param (string) $mode What to return: raw (all), base (before '?'), uri (before '?', without the domain).
139
+ *
140
+ * @return (string)
141
+ */
142
+ function sfml_get_current_url( $mode = 'base' ) {
143
+ $mode = (string) $mode;
144
+ $port = (int) $_SERVER['SERVER_PORT'];
145
+ $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : '';
146
+ $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' );
147
+ $url = 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url;
148
+
149
+ switch ( $mode ) :
150
+ case 'raw' :
151
+ return $url;
152
+ case 'uri' :
153
+ $home = set_url_scheme( home_url() );
154
+ $url = explode( '?', $url, 2 );
155
+ $url = reset( $url );
156
+ $url = str_replace( $home, '', $url );
157
+ return trim( $url, '/' );
158
+ default :
159
+ $url = explode( '?', $url, 2 );
160
+ return reset( $url );
161
+ endswitch;
162
+ }
163
+
164
+
165
+ /**
166
+ * Get the absolute filesystem path to the root of the WordPress installation.
167
+ * This is a clone of `get_home_path()`. We don't use the real one because of a bug in old versions.
168
+ *
169
+ * @return (string) Full filesystem path to the root of the WordPress installation
170
+ */
171
+ function sfml_get_home_path() {
172
+ $home = set_url_scheme( get_option( 'home' ), 'http' );
173
+ $siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' );
174
+
175
+ if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
176
+ $wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
177
+ $pos = strripos( str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) );
178
+ $home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos );
179
+ $home_path = trailingslashit( $home_path );
180
+ } else {
181
+ $home_path = ABSPATH;
182
+ }
183
+
184
+ return str_replace( '\\', '/', $home_path );
185
+ }
186
+
187
+
188
+ /**
189
+ * Format a path with no heading slash and a trailing slash.
190
+ * If the path is empty, it returns an empty string, not a lonely slash.
191
+ * Example: foo/bar/
192
+ *
193
+ * @param (string) $slug A path.
194
+ *
195
+ * @return (string) The path with no heading slash and a trailing slash.
196
+ */
197
+ function sfml_trailingslash_only( $slug ) {
198
+ return ltrim( trim( $slug, '/' ) . '/', '/' );
199
+ }
200
+
201
+
202
+ /**
203
+ * Has WP its own directory?
204
+ *
205
+ * @see http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
206
+ *
207
+ * @return (string) The directory containing WP.
208
+ */
209
+ function sfml_get_wp_directory() {
210
+ static $wp_siteurl_subdir;
211
+
212
+ if ( isset( $wp_siteurl_subdir ) ) {
213
+ return $wp_siteurl_subdir;
214
+ }
215
+
216
+ $wp_siteurl_subdir = '';
217
+
218
+ $home = set_url_scheme( rtrim( get_option( 'home' ), '/' ), 'http' );
219
+ $siteurl = set_url_scheme( rtrim( get_option( 'siteurl' ), '/' ), 'http' );
220
+
221
+ if ( $home && 0 !== strcasecmp( $home, $siteurl ) ) {
222
+ $wp_siteurl_subdir = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
223
+ $wp_siteurl_subdir = sfml_trailingslash_only( $wp_siteurl_subdir );
224
+ }
225
+
226
+ return $wp_siteurl_subdir;
227
+ }
228
+
229
+
230
+ /**
231
+ * Build a string for html attributes (means: separated by a space).
232
+ * Example:
233
+ * array( 'width' => '200', 'height' => '150', 'yolo' => 'foo' )
234
+ * ==>
235
+ * ' width="200" height="150" yolo="foo"'
236
+ *
237
+ * @param (array) $attributes An array of attributes.
238
+ * @param (string) $quote Quote style to use.
239
+ *
240
+ * @return (string)
241
+ */
242
+ function sfml_build_html_atts( $attributes, $quote = '"' ) {
243
+ $out = '';
244
+
245
+ if ( ! $attributes || ! is_array( $attributes ) ) {
246
+ return '';
247
+ }
248
+
249
+ foreach ( $attributes as $att_name => $att_value ) {
250
+ $out .= ' ' . esc_attr( $att_name ) . '=' . $quote . esc_attr( $att_value ) . $quote;
251
+ }
252
+
253
+ return $out;
254
+ }
255
+
256
+
257
+ /**
258
+ * Remove rewrite rules and then recreate rewrite rules.
259
+ * Waits until the 'init' action to do so.
260
+ */
261
+ function sfml_maybe_flush_rewrite_rules() {
262
+ static $done = false;
263
+
264
+ if ( did_action( 'init' ) ) {
265
+ flush_rewrite_rules();
266
+ } elseif ( ! $done ) {
267
+ $done = true;
268
+ add_action( 'init', 'flush_rewrite_rules', PHP_INT_MAX );
269
+ }
270
+ }
271
+
272
+
273
+ /*------------------------------------------------------------------------------------------------*/
274
+ /* !VARIOUS ===================================================================================== */
275
+ /*------------------------------------------------------------------------------------------------*/
276
+
277
+ /**
278
+ * Small helper to (maybe) include `rewrite.php` file.
279
+ */
280
+ function sfml_include_rewrite_file() {
281
+ include_once( SFML_PLUGIN_DIR . 'inc/functions/rewrite.php' );
282
+ }
283
+
284
+
285
+ /**
286
+ * Tell if the `.htaccess` or `web.config` file is writable.
287
+ * If the file does not exist (uh?), check if the parent folder is writable.
288
+ *
289
+ * @return (bool) True if the file is writable. False otherwize.
290
+ */
291
+ function sfml_can_write_file() {
292
+ global $is_apache, $is_iis7;
293
+
294
+ $home_path = sfml_get_home_path();
295
+
296
+ // Apache.
297
+ if ( $is_apache ) {
298
+ if ( ! got_mod_rewrite() ) {
299
+ return false;
300
+ }
301
+ if ( wp_is_writable( $home_path . '.htaccess' ) ) {
302
+ return true;
303
+ }
304
+ return ! file_exists( $home_path . '.htaccess' ) && wp_is_writable( $home_path );
305
+ }
306
+
307
+ // IIS7.
308
+ if ( $is_iis7 ) {
309
+ if ( ! iis7_supports_permalinks() ) {
310
+ return false;
311
+ }
312
+ if ( wp_is_writable( $home_path . 'web.config' ) ) {
313
+ return true;
314
+ }
315
+ return ! file_exists( $home_path . 'web.config' ) && wp_is_writable( $home_path );
316
+ }
317
+
318
+ return false;
319
+ }
inc/redirections-and-dies.php CHANGED
@@ -7,69 +7,158 @@ if ( ! defined( 'ABSPATH' ) ) {
7
  /* !REMOVE DEFAULT WORDPRESS REDIRECTIONS TO LOGIN AND ADMIN AREAS ============================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
 
 
 
 
 
10
  remove_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );
11
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /*------------------------------------------------------------------------------------------------*/
14
- /* !IF THE CURRENT URI IS NOT LISTED IN OUR SLUGS, DENY ACCESS TO THE FORM ====================== */
15
  /*------------------------------------------------------------------------------------------------*/
16
 
17
- add_action( 'login_init', 'sfml_login_init', 0 );
18
-
19
- function sfml_login_init() {
 
 
 
20
  // If the user is logged in, do nothing, lets WP redirect this user to the administration area.
21
  if ( is_user_logged_in() ) {
22
  return;
23
  }
24
 
25
- $uri = sf_get_current_url( 'uri' );
26
- $subdir = sfml_wp_directory();
27
- $slugs = sfml_get_slugs();
28
- if ( $subdir ) {
 
29
  foreach ( $slugs as $action => $slug ) {
30
- $slugs[ $action ] = $subdir . $slug;
31
  }
32
  }
33
- // If you want to display the login form somewhere outside wp-login.php, add your URIs here.
34
- $new_slugs = apply_filters( 'sfml_slugs_not_to_kill', array(), $uri, $subdir, $slugs );
35
- $slugs = is_array( $new_slugs ) && ! empty( $new_slugs ) ? array_merge( $new_slugs, $slugs ) : $slugs;
36
 
37
- if ( ! in_array( $uri, $slugs ) ) {
38
- do_action( 'sfml_wp_login_error' );
 
 
 
 
 
 
 
 
 
39
 
40
- // To make sure something happen.
41
- if ( false === has_action( 'sfml_wp_login_error' ) ) {
42
- sfml_wp_login_error();
 
 
43
  }
 
44
  }
 
 
 
45
  }
46
 
47
 
48
- add_action( 'sfml_wp_login_error', 'sfml_wp_login_error' );
 
 
 
 
 
 
 
 
49
 
50
- function sfml_wp_login_error() {
51
- $do = sfml_deny_wp_login_access();
52
 
53
  switch ( $do ) {
54
  case 2:
55
  $redirect = $GLOBALS['wp_rewrite']->using_permalinks() ? home_url( '404' ) : add_query_arg( 'p', '404', home_url() );
56
- wp_safe_redirect( esc_url( user_trailingslashit( apply_filters( 'sfml_404_error_page', $redirect ) ) ) );
 
 
 
 
 
 
57
  exit;
58
  case 3:
59
- wp_safe_redirect( esc_url( user_trailingslashit( home_url() ) ) );
60
  exit;
61
  default:
62
- wp_die( __( 'No no no, the login form is not here.', 'sf-move-login' ), __( 'Nope :)', 'sf-move-login' ), array( 'response' => 501 ) );
63
  }
64
  }
65
 
66
 
67
  /*------------------------------------------------------------------------------------------------*/
68
- /* !IF NOT CONNECTED, DO NOT REDIRECT FROM WP-SIGNUP.PHP AND WP-REGISTER.PHP TO WP-LOGIN.PHP ==== */
69
  /*------------------------------------------------------------------------------------------------*/
70
 
71
- add_filter( 'register_url', 'sfml_maybe_die_on_signup_page' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
 
 
 
 
 
 
 
 
 
 
73
  function sfml_maybe_die_on_signup_page( $url ) {
74
  if ( empty( $_SERVER['REQUEST_URI'] ) ) {
75
  return $url;
@@ -81,55 +170,34 @@ function sfml_maybe_die_on_signup_page( $url ) {
81
  return $url;
82
  }
83
 
84
- do_action( 'sfml_wp_login_error' );
85
-
86
- // To make sure something happen.
87
- if ( false === has_action( 'sfml_wp_login_error' ) ) {
88
- sfml_wp_login_error();
89
- }
90
- }
91
-
92
-
93
- /*------------------------------------------------------------------------------------------------*/
94
- /* !IF NOT CONNECTED, DO NOT REDIRECT FROM ADMIN AREA TO WP-LOGIN.PHP =========================== */
95
- /*------------------------------------------------------------------------------------------------*/
96
-
97
- add_action( 'after_setup_theme', 'sfml_maybe_die_before_admin_redirect', 12 );
98
-
99
- function sfml_maybe_die_before_admin_redirect() {
100
- global $pagenow;
101
- // If it's not the administration area, or if it's an ajax call, no need to go further.
102
- if ( ! ( is_admin() && ! ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( 'admin-post.php' === $pagenow && ! empty( $_REQUEST['action'] ) ) ) ) ) {
103
- return;
104
- }
105
-
106
- $scheme = is_user_admin() ? 'logged_in' : apply_filters( 'auth_redirect_scheme', '' );
107
-
108
- if ( ! wp_validate_auth_cookie( '', $scheme ) && sfml_deny_admin_access() ) {
109
- do_action( 'sfml_wp_admin_error' );
110
-
111
- // To make sure something happen.
112
- if ( false === has_action( 'sfml_wp_admin_error' ) ) {
113
- sfml_wp_admin_error();
114
- }
115
- }
116
  }
117
 
118
 
119
- add_action( 'sfml_wp_admin_error', 'sfml_wp_admin_error' );
 
 
 
 
 
 
 
 
120
 
121
- function sfml_wp_admin_error() {
122
- $do = sfml_deny_admin_access();
123
 
124
  switch ( $do ) {
125
  case 1:
126
- wp_die( __( 'Cheatin&#8217; uh?' ), __( 'Nope :)', 'sf-move-login' ), array( 'response' => 501 ) );
127
  case 2:
128
  $redirect = $GLOBALS['wp_rewrite']->using_permalinks() ? home_url( '404' ) : add_query_arg( 'p', '404', home_url() );
129
- wp_safe_redirect( esc_url( user_trailingslashit( apply_filters( 'sfml_404_error_page', $redirect ) ) ) );
 
 
130
  exit;
131
  case 3:
132
- wp_safe_redirect( esc_url( user_trailingslashit( home_url() ) ) );
133
  exit;
134
  }
135
  }
7
  /* !REMOVE DEFAULT WORDPRESS REDIRECTIONS TO LOGIN AND ADMIN AREAS ============================== */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
+ /**
11
+ * WordPress redirects some URLs (`wp-admin`, `dashboard`, `admin`) to the administration area,
12
+ * and some others (`wp-login.php`, `login`) to the login page.
13
+ * We don't want that, so we remove the hook.
14
+ */
15
  remove_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );
16
 
17
 
18
+ add_filter( 'rewrite_rules_array', 'sfml_remove_rewrite_rules' );
19
+ /**
20
+ * Filter the full set of generated rewrite rules.
21
+ *
22
+ * @since 2.4
23
+ *
24
+ * @param (array) $rules The compiled array of rewrite rules.
25
+ *
26
+ * @return (array)
27
+ */
28
+ function sfml_remove_rewrite_rules( $rules ) {
29
+ if ( ! is_multisite() ) {
30
+ unset( $rules['.*wp-register.php$'] );
31
+ }
32
+ return $rules;
33
+ }
34
+
35
+
36
  /*------------------------------------------------------------------------------------------------*/
37
+ /* !DENY ACCESS TO THE FORM ===================================================================== */
38
  /*------------------------------------------------------------------------------------------------*/
39
 
40
+ add_action( 'login_init', 'sfml_maybe_deny_login_page', 0 );
41
+ /**
42
+ * When displaying the login page, if the URL does not matches those in our settings, deny access.
43
+ * Does nothing if the user is logged in.
44
+ */
45
+ function sfml_maybe_deny_login_page() {
46
  // If the user is logged in, do nothing, lets WP redirect this user to the administration area.
47
  if ( is_user_logged_in() ) {
48
  return;
49
  }
50
 
51
+ $uri = sfml_get_current_url( 'uri' );
52
+ $wp_dir = sfml_get_wp_directory();
53
+ $slugs = sfml_get_slugs();
54
+
55
+ if ( $wp_dir ) {
56
  foreach ( $slugs as $action => $slug ) {
57
+ $slugs[ $action ] = $wp_dir . $slug;
58
  }
59
  }
 
 
 
60
 
61
+ /**
62
+ * If you want to display the login form somewhere outside wp-login.php, add your URIs here.
63
+ *
64
+ * @param (array) $new_slugs An array of action => URIs (WP directory + slugs).
65
+ * @param (string) $uri The current URI.
66
+ * @param (string) $wp_dir Path to WordPress.
67
+ * @param (array) $slugs URIs already in use.
68
+ */
69
+ $new_slugs = apply_filters( 'sfml_slugs_not_to_kill', array(), $uri, $wp_dir, $slugs );
70
+ $slugs = is_array( $new_slugs ) && ! empty( $new_slugs ) ? array_merge( $new_slugs, $slugs ) : $slugs;
71
+ $slugs = array_flip( $slugs );
72
 
73
+ if ( isset( $slugs[ $uri ] ) ) {
74
+ // Display the login page.
75
+ if ( ! defined( 'DONOTCACHEPAGE' ) ) {
76
+ // Tell cache plugins not to cache the login page.
77
+ define( 'DONOTCACHEPAGE', true );
78
  }
79
+ return;
80
  }
81
+
82
+ // You shall not pass!
83
+ sfml_deny_login_access();
84
  }
85
 
86
 
87
+ /**
88
+ * Perform the action set for the login page: die or redirect.
89
+ */
90
+ function sfml_deny_login_access() {
91
+ /**
92
+ * If you want to trigger a custom action (redirect, message, die...), add it here.
93
+ * Don't forget to exit/die.
94
+ */
95
+ do_action( 'sfml_wp_login_error' );
96
 
97
+ $do = sfml_get_deny_wp_login_access();
 
98
 
99
  switch ( $do ) {
100
  case 2:
101
  $redirect = $GLOBALS['wp_rewrite']->using_permalinks() ? home_url( '404' ) : add_query_arg( 'p', '404', home_url() );
102
+ /**
103
+ * Filter the 404 page URL.
104
+ *
105
+ * @param (string) $redirect An URL that leads to a 404 response.
106
+ */
107
+ $redirect = apply_filters( 'sfml_404_error_page', $redirect );
108
+ wp_redirect( esc_url_raw( user_trailingslashit( $redirect ) ) );
109
  exit;
110
  case 3:
111
+ wp_redirect( esc_url_raw( user_trailingslashit( home_url() ) ) );
112
  exit;
113
  default:
114
+ wp_die( __( 'No no no, the login form is not here.', 'sf-move-login' ), __( 'Nope :)', 'sf-move-login' ), array( 'response' => 403 ) );
115
  }
116
  }
117
 
118
 
119
  /*------------------------------------------------------------------------------------------------*/
120
+ /* !DO NOT REDIRECT TO THE NEW LOGIN PAGE ======================================================= */
121
  /*------------------------------------------------------------------------------------------------*/
122
 
123
+ add_action( 'after_setup_theme', 'sfml_maybe_deny_admin_redirect', 5 );
124
+ /**
125
+ * When a logged out user tries to access the admin area, deny access.
126
+ * Does nothing if the user is logged in.
127
+ * `admin-post.php` and `admin-ajax.php` are white listed.
128
+ */
129
+ function sfml_maybe_deny_admin_redirect() {
130
+ global $pagenow;
131
+ // If it's not the administration area, or if it's an ajax call, no need to go further.
132
+ if ( ! ( is_admin() && ! ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( 'admin-post.php' === $pagenow && ! empty( $_REQUEST['action'] ) ) ) ) ) {
133
+ return;
134
+ }
135
+
136
+ if ( is_user_admin() ) {
137
+ $scheme = 'logged_in';
138
+ } else {
139
+ /** This filter is documented in wp-includes/pluggable.php */
140
+ $scheme = apply_filters( 'auth_redirect_scheme', '' );
141
+ }
142
+
143
+ if ( wp_validate_auth_cookie( '', $scheme ) ) {
144
+ return;
145
+ }
146
+
147
+ // Nice try. But no.
148
+ sfml_deny_login_redirect();
149
+ }
150
+
151
 
152
+ add_filter( 'register_url', 'sfml_maybe_die_on_signup_page' );
153
+ /**
154
+ * When a logged out user tries to access `wp-signup.php` or `wp-register.php`, deny access.
155
+ * Does nothing if the user is logged in.
156
+ * Does nothing in multisite.
157
+ *
158
+ * @param (string) $url The URL.
159
+ *
160
+ * @return (string) The same URL.
161
+ */
162
  function sfml_maybe_die_on_signup_page( $url ) {
163
  if ( empty( $_SERVER['REQUEST_URI'] ) ) {
164
  return $url;
170
  return $url;
171
  }
172
 
173
+ // Nope!
174
+ sfml_deny_login_redirect();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
 
178
+ /**
179
+ * Perform the action set for redirections to login page: die or redirect.
180
+ */
181
+ function sfml_deny_login_redirect() {
182
+ /**
183
+ * If you want to trigger a custom action (redirect, message, die...), add it here.
184
+ * Don't forget to exit/die.
185
+ */
186
+ do_action( 'sfml_wp_admin_error' );
187
 
188
+ $do = sfml_get_deny_admin_access();
 
189
 
190
  switch ( $do ) {
191
  case 1:
192
+ wp_die( __( 'Cheatin&#8217; uh?' ), __( 'Nope :)', 'sf-move-login' ), array( 'response' => 403 ) );
193
  case 2:
194
  $redirect = $GLOBALS['wp_rewrite']->using_permalinks() ? home_url( '404' ) : add_query_arg( 'p', '404', home_url() );
195
+ /** This filter is documented in inc/redirections-and-dies.php */
196
+ $redirect = apply_filters( 'sfml_404_error_page', $redirect );
197
+ wp_redirect( esc_url_raw( user_trailingslashit( $redirect ) ) );
198
  exit;
199
  case 3:
200
+ wp_redirect( esc_url_raw( user_trailingslashit( home_url() ) ) );
201
  exit;
202
  }
203
  }
inc/rewrite.php DELETED
@@ -1,432 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) {
3
- die( 'Cheatin\' uh?' );
4
- }
5
-
6
- /*------------------------------------------------------------------------------------------------*/
7
- /* !INCLUDES ==================================================================================== */
8
- /*------------------------------------------------------------------------------------------------*/
9
-
10
- require_once( ABSPATH . WPINC . '/functions.php' );
11
- require_once( ABSPATH . 'wp-admin/includes/misc.php' );
12
-
13
-
14
- /*------------------------------------------------------------------------------------------------*/
15
- /* !REWRITE RULES =============================================================================== */
16
- /*------------------------------------------------------------------------------------------------*/
17
-
18
- // !Return an array of action => url
19
-
20
- function sfml_rules( $actions = null ) {
21
- if ( is_null( $actions ) ) {
22
- if ( ! class_exists( 'SFML_Options' ) ) {
23
- include( SFML_PLUGIN_DIR . 'inc/class-sfml-options.php' );
24
- SFML_Options::init();
25
- }
26
-
27
- $actions = SFML_Options::get_slugs();
28
- }
29
-
30
- $rules = array(
31
- $actions['login'] => 'wp-login.php',
32
- );
33
-
34
- unset( $actions['login'] );
35
-
36
- foreach ( $actions as $action => $slug ) {
37
- $rules[ $slug ] = 'wp-login.php?action=' . $action;
38
- }
39
-
40
- return $rules;
41
- }
42
-
43
-
44
- // !Write rules in file.
45
- // @return (bool) false if no rewrite module or not IIS7/Apache
46
-
47
- function sfml_write_rules( $rules = null ) {
48
- global $is_apache, $is_iis7;
49
-
50
- $rules = is_null( $rules ) ? sfml_rules() : $rules;
51
-
52
- // Nginx
53
- if ( sfml_is_nginx() ) {
54
- return true;
55
- }
56
-
57
- if ( ! sfml_can_write_file() ) {
58
- return false;
59
- }
60
-
61
- // IIS
62
- if ( $is_iis7 ) {
63
- return sfml_insert_iis7_rewrite_rules( 'SF Move Login', sfml_iis7_rewrite_rules( $rules, 'SF Move Login' ) );
64
- }
65
- // Apache
66
- elseif ( $is_apache ) {
67
- return sfml_insert_apache_rewrite_rules( 'SF Move Login', sfml_apache_rewrite_rules( $rules ) );
68
- }
69
-
70
- return false;
71
- }
72
-
73
-
74
- // !Is it a nginx server?
75
-
76
- function sfml_is_nginx() {
77
- global $is_nginx;
78
-
79
- if ( is_null( $is_nginx ) ) {
80
- $is_nginx = ! empty( $_SERVER['SERVER_SOFTWARE'] ) && strpos( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) !== false;
81
- }
82
-
83
- return $is_nginx;
84
- }
85
-
86
-
87
- /*
88
- * !Tell if the .htaccess/web.config file is writable.
89
- * If the file does not exists (uh?), check if the parent folder is writable.
90
- */
91
-
92
- function sfml_can_write_file() {
93
- global $is_apache, $is_iis7;
94
-
95
- $home_path = sfml_get_home_path();
96
-
97
- // IIS7
98
- if ( $is_iis7 && iis7_supports_permalinks() && ( wp_is_writable( $home_path . 'web.config' ) || ( ! file_exists( $home_path . 'web.config' ) && wp_is_writable( $home_path ) ) ) ) {
99
- return true;
100
- }
101
- // Apache
102
- elseif ( $is_apache && got_mod_rewrite() && ( wp_is_writable( $home_path . '.htaccess' ) || ( ! file_exists( $home_path . '.htaccess' ) && wp_is_writable( $home_path ) ) ) ) {
103
- return true;
104
- }
105
-
106
- return false;
107
- }
108
-
109
-
110
- // !Is WP a MultiSite and a subfolder install?
111
-
112
- function sfml_is_subfolder_install() {
113
- global $wpdb;
114
- static $subfolder_install;
115
-
116
- if ( ! isset( $subfolder_install ) ) {
117
- if ( is_multisite() ) {
118
-
119
- $subfolder_install = ! (bool) is_subdomain_install();
120
-
121
- } elseif ( ! is_null( $wpdb->sitemeta ) ) {
122
-
123
- $subfolder_install = ! (bool) $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
124
-
125
- } else {
126
-
127
- $subfolder_install = false;
128
-
129
- }
130
- }
131
-
132
- return $subfolder_install;
133
- }
134
-
135
-
136
- /*------------------------------------------------------------------------------------------------*/
137
- /* !REWRITE RULES: NGINX ======================================================================== */
138
- /*------------------------------------------------------------------------------------------------*/
139
-
140
- // !Return the multisite rewrite rules (as an array).
141
-
142
- function sfml_nginx_rewrite_rules( $rules = array() ) {
143
- if ( ! is_array( $rules ) || empty( $rules ) ) {
144
- return '';
145
- }
146
-
147
- $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
148
- $subdir_base = sfml_trailingslash_only( $base );
149
-
150
- if ( sfml_is_subfolder_install() ) {
151
- $wp_siteurl_subdir = '';
152
- $subdir_match = '([_0-9a-zA-Z-]+/)' . ( sfml_wp_directory() ? '' : '?' );
153
- $subdir_repl = '$1';
154
- } else {
155
- $wp_siteurl_subdir = sfml_wp_directory();
156
- $subdir_match = '';
157
- $subdir_repl = '';
158
- }
159
-
160
- $out = array(
161
- 'location ' . $base . ' {',
162
- );
163
-
164
- foreach ( $rules as $slug => $rule ) {
165
- $out[] = ' rewrite ^' . $wp_siteurl_subdir . $subdir_match . $slug . '/?$ /' . $subdir_base . $wp_siteurl_subdir . $subdir_repl . $rule . ' break;';
166
- }
167
-
168
- $out[] = '}';
169
-
170
- return $out;
171
- }
172
-
173
-
174
- /*------------------------------------------------------------------------------------------------*/
175
- /* !REWRITE RULES: APACHE ======================================================================= */
176
- /*------------------------------------------------------------------------------------------------*/
177
-
178
- // !Return the multisite rewrite rules (as an array).
179
-
180
- function sfml_apache_rewrite_rules( $rules = array() ) {
181
- if ( ! is_array( $rules ) || empty( $rules ) ) {
182
- return '';
183
- }
184
-
185
- $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
186
-
187
- if ( sfml_is_subfolder_install() ) {
188
- $wp_siteurl_subdir = '';
189
- $subdir_match = '([_0-9a-zA-Z-]+/)' . ( sfml_wp_directory() ? '' : '?' );
190
- $subdir_repl = '$1';
191
- } else {
192
- $wp_siteurl_subdir = sfml_wp_directory();
193
- $subdir_match = '';
194
- $subdir_repl = '';
195
- }
196
-
197
- $out = array(
198
- '<IfModule mod_rewrite.c>',
199
- ' RewriteEngine On',
200
- ' RewriteBase ' . $base,
201
- );
202
-
203
- foreach ( $rules as $slug => $rule ) {
204
- $out[] = ' RewriteRule ^' . $wp_siteurl_subdir . $subdir_match . $slug . '/?$ ' . $wp_siteurl_subdir . $subdir_repl . $rule . ' [QSA,L]';
205
- }
206
-
207
- $out[] = '</IfModule>';
208
-
209
- return $out;
210
- }
211
-
212
-
213
- // !Insert content in htaccess file, before the WP block.
214
- // @param $marker string
215
- // @param $rules array|string
216
- // @param $before string
217
-
218
- function sfml_insert_apache_rewrite_rules( $marker, $rules = '', $before = '# BEGIN WordPress' ) {
219
- if ( ! $marker ) {
220
- return false;
221
- }
222
-
223
- $home_path = sfml_get_home_path();
224
- $htaccess_file = $home_path . '.htaccess';
225
-
226
- $has_htaccess = file_exists( $htaccess_file );
227
- $htaccess_is_writable = $has_htaccess && is_writeable( $htaccess_file );
228
- $got_mod_rewrite = got_mod_rewrite();
229
-
230
- if (
231
- ( $htaccess_is_writable && ! $rules ) || // Remove rules
232
- ( $htaccess_is_writable && $rules && $got_mod_rewrite ) || // Add rules
233
- ( ! $has_htaccess && is_writeable( $home_path ) && $rules && $got_mod_rewrite ) // Create htaccess + add rules
234
- ) {
235
- // Current htaccess content
236
- $htaccess_content = $has_htaccess ? file_get_contents( $htaccess_file ) : '';
237
-
238
- // No "before tag"?
239
- if ( ! $before && $rules ) {
240
- return insert_with_markers( $htaccess_file, $marker, $rules );
241
- }
242
-
243
- // Remove the SF Move Login marker
244
- $htaccess_content = preg_replace( "/# BEGIN $marker.*# END $marker\n*/is", '', $htaccess_content );
245
-
246
- // New content
247
- if ( $before && $rules ) {
248
-
249
- $rules = is_array( $rules ) ? implode( "\n", $rules ) : $rules;
250
- $rules = trim( $rules, "\r\n " );
251
-
252
- if ( $rules ) {
253
- // No WordPress rules? (as in multisite)
254
- if ( false === strpos( $htaccess_content, $before ) ) {
255
- // The new content needs to be inserted at the begining of the file.
256
- $htaccess_content = "# BEGIN $marker\n$rules\n# END $marker\n\n\n$htaccess_content";
257
- } else {
258
- // The new content needs to be inserted before the WordPress rules.
259
- $rules = "# BEGIN $marker\n$rules\n# END $marker\n\n\n$before";
260
- $htaccess_content = str_replace( $before, $rules, $htaccess_content );
261
- }
262
- }
263
- }
264
-
265
- // Update the .htacces file
266
- return (bool) file_put_contents( $htaccess_file , $htaccess_content );
267
- }
268
-
269
- return false;
270
- }
271
-
272
-
273
- /*------------------------------------------------------------------------------------------------*/
274
- /* !REWRITE RULES: IIS ========================================================================== */
275
- /*------------------------------------------------------------------------------------------------*/
276
-
277
- // !Return the multisite rewrite rules for IIS systems (as a part of a xml system).
278
-
279
- function sfml_iis7_rewrite_rules( $rules = array(), $marker = null ) {
280
- if ( ! is_array( $rules ) || empty( $rules ) || empty( $marker ) ) {
281
- return '';
282
- }
283
-
284
- $base = sfml_trailingslash_only( parse_url( get_option( 'home' ), PHP_URL_PATH ) );
285
-
286
- if ( sfml_is_subfolder_install() ) {
287
- $wp_siteurl_subdir = $base;
288
- $subdir_match = '([_0-9a-zA-Z-]+/)' . ( sfml_wp_directory() ? '' : '?' );
289
- $subdir_repl = '{R:1}';
290
- } else {
291
- $wp_siteurl_subdir = $base . sfml_wp_directory();
292
- $subdir_match = '';
293
- $subdir_repl = '';
294
- }
295
-
296
- $rule_i = 1;
297
- $space = str_repeat( ' ', 16 );
298
- $out = array();
299
-
300
- foreach ( $rules as $slug => $rule ) {
301
- $out[] = $space . '<rule name="' . $marker . ' Rule ' . $rule_i . '" stopProcessing="true">' . "\n"
302
- . $space . ' <match url="^' . $wp_siteurl_subdir . $subdir_match . $slug . '/?$" ignoreCase="false" />' . "\n"
303
- . $space . ' <action type="Redirect" url="' . $wp_siteurl_subdir . $subdir_repl . $rule . '" redirectType="Permanent" />' . "\n"
304
- . $space . "</rule>\n";
305
- $rule_i++;
306
- }
307
-
308
- return $out;
309
- }
310
-
311
-
312
- // !Insert content in web.config file, before the WP block.
313
- // @var $rules array|string
314
-
315
- function sfml_insert_iis7_rewrite_rules( $marker, $rules = '', $before = 'wordpress' ) {
316
- if ( ! $marker || ! class_exists( 'DOMDocument' ) ) {
317
- return false;
318
- }
319
-
320
- $home_path = sfml_get_home_path();
321
- $web_config_file = $home_path . 'web.config';
322
-
323
- $has_web_config = file_exists( $web_config_file );
324
- $web_config_is_writable = $has_web_config && wp_is_writable( $web_config_file );
325
- $supports_permalinks = iis7_supports_permalinks();
326
-
327
- // New content
328
- $rules = is_array( $rules ) ? implode( "\n", $rules ) : $rules;
329
- $rules = trim( $rules, "\r\n" );
330
-
331
- if (
332
- ( $web_config_is_writable && ! $rules ) || // Remove rules
333
- ( $web_config_is_writable && $rules && $supports_permalinks ) || // Add rules
334
- ( ! $has_web_config && wp_is_writable( $home_path ) && $rules && $supports_permalinks ) // Create web.config + add rules
335
- ) {
336
- // If configuration file does not exist then we create one.
337
- if ( ! $has_web_config ) {
338
- $fp = fopen( $web_config_file, 'w' );
339
- fwrite( $fp, '<configuration/>' );
340
- fclose( $fp );
341
- }
342
-
343
- $doc = new DOMDocument();
344
- $doc->preserveWhiteSpace = false;
345
-
346
- if ( false === $doc->load( $web_config_file ) ) {
347
- return false;
348
- }
349
-
350
- $xpath = new DOMXPath( $doc );
351
-
352
- // Remove old rules
353
- $old_rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'' . $marker . '\')]' );
354
-
355
- if ( $old_rules->length > 0 ) {
356
- $child = $old_rules->item( 0 );
357
- $parent = $child->parentNode;
358
- $parent->removeChild( $child );
359
- }
360
-
361
- // No new rules?
362
- if ( ! $rules ) {
363
- $doc->formatOutput = true;
364
- saveDomDocument( $doc, $web_config_file );
365
- return true;
366
- }
367
-
368
- // Check the XPath to the rewrite rule and create XML nodes if they do not exist
369
- $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite/rules' );
370
-
371
- if ( $xmlnodes->length > 0 ) {
372
- $rules_node = $xmlnodes->item( 0 );
373
- } else {
374
- $rules_node = $doc->createElement( 'rules' );
375
-
376
- $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite' );
377
-
378
- if ( $xmlnodes->length > 0 ) {
379
- $rewrite_node = $xmlnodes->item( 0 );
380
- $rewrite_node->appendChild( $rules_node );
381
- } else {
382
- $rewrite_node = $doc->createElement( 'rewrite' );
383
- $rewrite_node->appendChild( $rules_node );
384
-
385
- $xmlnodes = $xpath->query( '/configuration/system.webServer' );
386
-
387
- if ( $xmlnodes->length > 0 ) {
388
- $system_webServer_node = $xmlnodes->item( 0 );
389
- $system_webServer_node->appendChild( $rewrite_node );
390
- } else {
391
- $system_webServer_node = $doc->createElement( 'system.webServer' );
392
- $system_webServer_node->appendChild( $rewrite_node );
393
-
394
- $xmlnodes = $xpath->query( '/configuration' );
395
-
396
- if ( $xmlnodes->length > 0 ) {
397
- $config_node = $xmlnodes->item( 0 );
398
- $config_node->appendChild( $system_webServer_node );
399
- } else {
400
- $config_node = $doc->createElement( 'configuration' );
401
- $doc->appendChild( $config_node );
402
- $config_node->appendChild( $system_webServer_node );
403
- }
404
- }
405
- }
406
- }
407
-
408
- $rule_fragment = $doc->createDocumentFragment();
409
- $rule_fragment->appendXML( $rules );
410
-
411
- // Insert before the WP rules
412
- if ( $before ) {
413
- $wordpress_rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'' . $before . '\')]' );
414
- }
415
-
416
- if ( $before && $wordpress_rules->length > 0 ) {
417
- $child = $wordpress_rules->item( 0 );
418
- $parent = $child->parentNode;
419
- $parent->insertBefore( $element, $child );
420
- } else {
421
- $rules_node->appendChild( $rule_fragment );
422
- }
423
-
424
- $doc->encoding = 'UTF-8';
425
- $doc->formatOutput = true;
426
- saveDomDocument( $doc, $web_config_file );
427
-
428
- return true;
429
- }
430
-
431
- return false;
432
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/url-filters.php CHANGED
@@ -7,35 +7,49 @@ if ( ! defined( 'ABSPATH' ) ) {
7
  /* !FILTER URLS ================================================================================= */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
10
- // !Site URL
11
-
12
  add_filter( 'site_url', 'sfml_site_url', 10, 4 );
13
-
 
 
 
 
 
 
 
 
 
 
14
  function sfml_site_url( $url, $path, $scheme, $blog_id = null ) {
15
  if ( ! empty( $path ) && is_string( $path ) && false === strpos( $path, '..' ) && 0 === strpos( ltrim( $path, '/' ), 'wp-login.php' ) ) {
16
  $blog_id = (int) $blog_id;
17
 
18
- // Base url
19
  if ( empty( $blog_id ) || get_current_blog_id() === $blog_id || ! is_multisite() ) {
20
  $url = get_option( 'siteurl' );
21
  } else {
22
- switch_to_blog( $blog_id );
23
- $url = get_option( 'siteurl' );
24
- restore_current_blog();
25
  }
26
 
27
  $url = set_url_scheme( $url, $scheme );
28
- return rtrim( $url, '/' ) . '/' . ltrim( sfml_set_path( $path ), '/' );
29
  }
30
 
31
  return $url;
32
  }
33
 
34
 
35
- // !Network site URL: don't use network_site_url() for the login URL ffs!
36
-
37
  add_filter( 'network_site_url', 'sfml_network_site_url', 10, 3 );
38
-
 
 
 
 
 
 
 
 
 
 
39
  function sfml_network_site_url( $url, $path, $scheme ) {
40
  if ( ! empty( $path ) && is_string( $path ) && false === strpos( $path, '..' ) && 0 === strpos( ltrim( $path, '/' ), 'wp-login.php' ) ) {
41
  return site_url( $path, $scheme );
@@ -45,29 +59,47 @@ function sfml_network_site_url( $url, $path, $scheme ) {
45
  }
46
 
47
 
48
- // !Logout url: wp_logout_url() add the action param after using site_url().
49
-
50
- add_filter( 'logout_url', 'sfml_logout_url', 1, 2 );
51
-
52
- function sfml_logout_url( $logout_url, $redirect ) {
 
 
 
 
 
 
53
  return sfml_login_to_action( $logout_url, 'logout' );
54
  }
55
 
56
 
57
- // !Forgot password url: wp_lostpassword_url() add the action param after using network_site_url().
58
-
59
- add_filter( 'lostpassword_url', 'sfml_lostpassword_url', 1, 2 );
60
-
61
- function sfml_lostpassword_url( $lostpassword_url, $redirect ) {
 
 
 
 
 
 
62
  return sfml_login_to_action( $lostpassword_url, 'lostpassword' );
63
  }
64
 
65
 
66
- // !Redirections are hard-coded.
67
-
68
- add_filter( 'wp_redirect', 'sfml_redirect', 10, 2 );
69
-
70
- function sfml_redirect( $location, $status ) {
 
 
 
 
 
 
71
  $base_uri = explode( '?', $location );
72
  $base_uri = reset( $base_uri );
73
 
@@ -79,11 +111,22 @@ function sfml_redirect( $location, $status ) {
79
  }
80
 
81
 
82
- // !Multisite: the "new site" welcome email.
83
-
84
- add_filter( 'update_welcome_email', 'sfml_update_welcome_email', 10, 6 );
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
- function sfml_update_welcome_email( $welcome_email, $blog_id, $user_id, $password, $title, $meta ) {
87
  $url = get_blogaddress_by_id( $blog_id );
88
 
89
  switch_to_blog( $blog_id );
@@ -92,3 +135,91 @@ function sfml_update_welcome_email( $welcome_email, $blog_id, $user_id, $passwor
92
 
93
  return str_replace( $url . 'wp-login.php', $login_url, $welcome_email );
94
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  /* !FILTER URLS ================================================================================= */
8
  /*------------------------------------------------------------------------------------------------*/
9
 
 
 
10
  add_filter( 'site_url', 'sfml_site_url', 10, 4 );
11
+ /**
12
+ * Filter the site URL.
13
+ *
14
+ * @param (string) $url The complete site URL including scheme and path.
15
+ * @param (string) $path Path relative to the site URL. Blank string if no path is specified.
16
+ * @param (string|null) $scheme Scheme to give the site URL context. Accepts 'http', 'https', 'login',
17
+ * 'login_post', 'admin', 'relative' or null.
18
+ * @param (int|null) $blog_id Blog ID, or null for the current blog.
19
+ *
20
+ * @return (string) The site URL.
21
+ */
22
  function sfml_site_url( $url, $path, $scheme, $blog_id = null ) {
23
  if ( ! empty( $path ) && is_string( $path ) && false === strpos( $path, '..' ) && 0 === strpos( ltrim( $path, '/' ), 'wp-login.php' ) ) {
24
  $blog_id = (int) $blog_id;
25
 
26
+ // Base url.
27
  if ( empty( $blog_id ) || get_current_blog_id() === $blog_id || ! is_multisite() ) {
28
  $url = get_option( 'siteurl' );
29
  } else {
30
+ $url = get_blog_option( $blog_id, 'siteurl' );
 
 
31
  }
32
 
33
  $url = set_url_scheme( $url, $scheme );
34
+ return rtrim( $url, '/' ) . sfml_set_path( $path );
35
  }
36
 
37
  return $url;
38
  }
39
 
40
 
 
 
41
  add_filter( 'network_site_url', 'sfml_network_site_url', 10, 3 );
42
+ /**
43
+ * Filter the network site URL: don't use `network_site_url()` for the login URL ffs!
44
+ *
45
+ * @param (string) $url The complete network site URL including scheme and path.
46
+ * @param (string) $path Path relative to the network site URL. Blank string if
47
+ * no path is specified.
48
+ * @param (string|null) $scheme Scheme to give the URL context. Accepts 'http', 'https',
49
+ * 'relative' or null.
50
+ *
51
+ * @return (string) The network site URL.
52
+ */
53
  function sfml_network_site_url( $url, $path, $scheme ) {
54
  if ( ! empty( $path ) && is_string( $path ) && false === strpos( $path, '..' ) && 0 === strpos( ltrim( $path, '/' ), 'wp-login.php' ) ) {
55
  return site_url( $path, $scheme );
59
  }
60
 
61
 
62
+ add_filter( 'logout_url', 'sfml_logout_url', 1 );
63
+ /**
64
+ * Filter the logout URL: `wp_logout_url()` add the action param after using `site_url()`.
65
+ *
66
+ * @since 1.0
67
+ *
68
+ * @param (string) $logout_url The Log Out URL.
69
+ *
70
+ * @return (string) The Log Out URL.
71
+ */
72
+ function sfml_logout_url( $logout_url ) {
73
  return sfml_login_to_action( $logout_url, 'logout' );
74
  }
75
 
76
 
77
+ add_filter( 'lostpassword_url', 'sfml_lostpassword_url', 1 );
78
+ /**
79
+ * Filter the Lost Password URL: `wp_lostpassword_url()` add the action param after using `network_site_url()`.
80
+ *
81
+ * @since 1.0
82
+ *
83
+ * @param (string) $lostpassword_url The lost password page URL.
84
+ *
85
+ * @return (string) The lost password page URL.
86
+ */
87
+ function sfml_lostpassword_url( $lostpassword_url ) {
88
  return sfml_login_to_action( $lostpassword_url, 'lostpassword' );
89
  }
90
 
91
 
92
+ add_filter( 'wp_redirect', 'sfml_redirect' );
93
+ /**
94
+ * Filter the redirect location: some redirections are hard-coded.
95
+ *
96
+ * @since 1.0
97
+ *
98
+ * @param (string) $location The path to redirect to.
99
+ *
100
+ * @return (string) The path to redirect to.
101
+ */
102
+ function sfml_redirect( $location ) {
103
  $base_uri = explode( '?', $location );
104
  $base_uri = reset( $base_uri );
105
 
111
  }
112
 
113
 
114
+ add_filter( 'update_welcome_email', 'sfml_update_welcome_email', 10, 2 );
115
+ /**
116
+ * Multisite: filter the content of the welcome email after site activation.
117
+ *
118
+ * @since 1.0
119
+ *
120
+ * @param (string) $welcome_email Message body of the email.
121
+ * @param (int) $blog_id Blog ID.
122
+ *
123
+ * @return (string) Message body of the email.
124
+ */
125
+ function sfml_update_welcome_email( $welcome_email, $blog_id ) {
126
+ if ( false === strpos( $welcome_email, 'wp-login.php' ) ) {
127
+ return $welcome_email;
128
+ }
129
 
 
130
  $url = get_blogaddress_by_id( $blog_id );
131
 
132
  switch_to_blog( $blog_id );
135
 
136
  return str_replace( $url . 'wp-login.php', $login_url, $welcome_email );
137
  }
138
+
139
+
140
+ /*------------------------------------------------------------------------------------------------*/
141
+ /* !UTILITIES =================================================================================== */
142
+ /*------------------------------------------------------------------------------------------------*/
143
+
144
+ /**
145
+ * Set the relative path: `wp-login.php?action=register -> /register`.
146
+ *
147
+ * @param (string) $path Path relative to the site URL.
148
+ *
149
+ * @return (string) The new path relative to the site URL, with our custom slug.
150
+ */
151
+ function sfml_set_path( $path ) {
152
+ $slugs = sfml_get_slugs();
153
+ $other = SFML_Options::get_instance()->get_other_actions();
154
+
155
+ // Get the action.
156
+ $parsed_path = parse_url( $path );
157
+
158
+ if ( ! empty( $parsed_path['query'] ) ) {
159
+ wp_parse_str( $parsed_path['query'], $params );
160
+ $action = ! empty( $params['action'] ) ? $params['action'] : 'login';
161
+
162
+ if ( isset( $params['key'] ) ) {
163
+ $action = 'resetpass';
164
+ }
165
+
166
+ if ( ! isset( $slugs[ $action ] ) && ! isset( $other[ $action ] ) && false === has_filter( 'login_form_' . $action ) ) {
167
+ $action = 'login';
168
+ }
169
+ } else {
170
+ $action = 'login';
171
+ }
172
+
173
+ // Set the path.
174
+ if ( isset( $slugs[ $action ] ) ) {
175
+ $path = str_replace( 'wp-login.php', $slugs[ $action ], $path );
176
+ $path = remove_query_arg( 'action', $path );
177
+ } else {
178
+ // In case of a custom action.
179
+ $path = str_replace( 'wp-login.php', $slugs['login'], $path );
180
+ $path = add_query_arg( 'action', $action, $path );
181
+ }
182
+
183
+ return '/' . ltrim( $path, '/' );
184
+ }
185
+
186
+
187
+ /**
188
+ * Set the URL: `login?action=logout -> /logout`.
189
+ * If the action is not present when we try to build the new URL, we fallback to `/login`. Then we can use this function after the action is added.
190
+ *
191
+ * @param (string) $link The URL.
192
+ * @param (string) $action The action.
193
+ *
194
+ * @return (string) The new URL, with our custom slug.
195
+ */
196
+ function sfml_login_to_action( $link, $action ) {
197
+ $slugs = sfml_get_slugs();
198
+ $need_action_param = false;
199
+
200
+ if ( isset( $slugs[ $action ] ) ) {
201
+ $slug = $slugs[ $action ];
202
+ } else {
203
+ // Shouldn't happen, because this function is not used in this case.
204
+ $slug = $slugs['login'];
205
+
206
+ if ( false === has_filter( 'login_form_' . $action ) ) {
207
+ $action = 'login';
208
+ } else {
209
+ // In case of a custom action.
210
+ $need_action_param = true;
211
+ }
212
+ }
213
+
214
+ if ( $link && false === strpos( $link, '/' . $slug ) ) {
215
+
216
+ $link = str_replace( array( '/' . $slugs['login'], '&amp;', '?amp;', '&' ), array( '/' . $slug, '&', '?', '&amp;' ), remove_query_arg( 'action', $link ) );
217
+
218
+ if ( $need_action_param ) {
219
+ // In case of a custom action, shouldn't happen.
220
+ $link = add_query_arg( 'action', $action, $link );
221
+ }
222
+ }
223
+
224
+ return $link;
225
+ }
inc/utilities.php DELETED
@@ -1,252 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) {
3
- die( 'Cheatin\' uh?' );
4
- }
5
-
6
- /*------------------------------------------------------------------------------------------------*/
7
- /* !OPTIONS ===================================================================================== */
8
- /*------------------------------------------------------------------------------------------------*/
9
-
10
- // !Get all options
11
-
12
- function sfml_get_options() {
13
- return SFML_Options::get_options();
14
- }
15
-
16
-
17
- // !Get default options
18
-
19
- function sfml_get_default_options() {
20
- return SFML_Options::get_default_options();
21
- }
22
-
23
-
24
- // !Get the slugs
25
-
26
- function sfml_get_slugs() {
27
- return SFML_Options::get_slugs();
28
- }
29
-
30
-
31
- // !Access to wp-login.php
32
-
33
- function sfml_deny_wp_login_access() {
34
- $options = sfml_get_options();
35
- return $options['deny_wp_login_access']; // 1: error message, 2: 404, 3: home
36
- }
37
-
38
-
39
- // !Access to the administration area
40
-
41
- function sfml_deny_admin_access() {
42
- $options = sfml_get_options();
43
- return $options['deny_admin_access']; // 0: nothing, 1: error message, 2: 404, 3: home
44
- }
45
-
46
-
47
- /*------------------------------------------------------------------------------------------------*/
48
- /* !UTILITIES =================================================================================== */
49
- /*------------------------------------------------------------------------------------------------*/
50
-
51
- // !Construct the url
52
-
53
- function sfml_set_path( $path ) {
54
- $slugs = sfml_get_slugs();
55
- $other = SFML_Options::get_other_actions();
56
-
57
- // Action
58
- $parsed_path = parse_url( $path );
59
-
60
- if ( ! empty( $parsed_path['query'] ) ) {
61
- wp_parse_str( $parsed_path['query'], $params );
62
- $action = ! empty( $params['action'] ) ? $params['action'] : 'login';
63
-
64
- if ( isset( $params['key'] ) ) {
65
- $action = 'resetpass';
66
- }
67
-
68
- if ( ! isset( $slugs[ $action ] ) && ! isset( $other[ $action ] ) && false === has_filter( 'login_form_' . $action ) ) {
69
- $action = 'login';
70
- }
71
- } else {
72
- $action = 'login';
73
- }
74
-
75
- // Path
76
- if ( isset( $slugs[ $action ] ) ) {
77
- $path = str_replace( 'wp-login.php', $slugs[ $action ], $path );
78
- $path = remove_query_arg( 'action', $path );
79
- } else {
80
- // In case of a custom action
81
- $path = str_replace( 'wp-login.php', $slugs['login'], $path );
82
- $path = remove_query_arg( 'action', $path );
83
- $path = add_query_arg( 'action', $action, $path );
84
- }
85
-
86
- return '/' . ltrim( $path, '/' );
87
- }
88
-
89
-
90
- // !login?action=logout -> /logout
91
-
92
- function sfml_login_to_action( $link, $action ) {
93
- $slugs = sfml_get_slugs();
94
- $need_action_param = false;
95
-
96
- if ( isset( $slugs[ $action ] ) ) {
97
- $slug = $slugs[ $action ];
98
- } else {
99
- // Shouldn't happen, because this function is not used in this case.
100
- $slug = $slugs['login'];
101
-
102
- if ( false === has_filter( 'login_form_' . $action ) ) {
103
- $action = 'login';
104
- } else {
105
- // In case of a custom action
106
- $need_action_param = true;
107
- }
108
- }
109
-
110
- if ( $link && false === strpos( $link, '/' . $slug ) ) {
111
-
112
- $link = str_replace( array( '/' . $slugs['login'], '&amp;', '?amp;', '&' ), array( '/' . $slug, '&', '?', '&amp;' ), remove_query_arg( 'action', $link ) );
113
-
114
- if ( $need_action_param ) {
115
- // In case of a custom action, shouldn't happen.
116
- $link = add_query_arg( 'action', $action, $link );
117
- }
118
- }
119
-
120
- return $link;
121
- }
122
-
123
-
124
- /*------------------------------------------------------------------------------------------------*/
125
- /* !GENERIC TOOLS =============================================================================== */
126
- /*------------------------------------------------------------------------------------------------*/
127
-
128
- // !Get current URL.
129
-
130
- if ( ! function_exists( 'sf_get_current_url' ) ) :
131
- function sf_get_current_url( $mode = 'base' ) {
132
- $mode = (string) $mode;
133
- $port = (int) $_SERVER['SERVER_PORT'];
134
- $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : '';
135
- $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' );
136
- $url = 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url;
137
-
138
- switch ( $mode ) :
139
- case 'raw' :
140
- return $url;
141
- case 'uri' :
142
- $home = set_url_scheme( home_url() );
143
- $url = explode( '?', $url, 2 );
144
- $url = reset( $url );
145
- $url = str_replace( $home, '', $url );
146
- return trim( $url, '/' );
147
- default :
148
- $url = explode( '?', $url, 2 );
149
- return reset( $url );
150
- endswitch;
151
- }
152
- endif;
153
-
154
-
155
- // !For WP < 3.4
156
-
157
- if ( ! function_exists( 'set_url_scheme' ) ) :
158
- function set_url_scheme( $url, $scheme = null ) {
159
- $orig_scheme = $scheme;
160
-
161
- if ( ! $scheme ) {
162
-
163
- $scheme = is_ssl() ? 'https' : 'http';
164
-
165
- } elseif ( 'admin' === $scheme || 'login' === $scheme || 'login_post' === $scheme || 'rpc' === $scheme ) {
166
-
167
- $scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http';
168
-
169
- } elseif ( 'http' !== $scheme && 'https' !== $scheme && 'relative' !== $scheme ) {
170
-
171
- $scheme = is_ssl() ? 'https' : 'http';
172
-
173
- }
174
-
175
- $url = trim( $url );
176
-
177
- if ( substr( $url, 0, 2 ) === '//' ) {
178
- $url = 'http:' . $url;
179
- }
180
-
181
- if ( 'relative' === $scheme ) {
182
-
183
- $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) );
184
-
185
- if ( '' !== $url && '/' === $url[0] ) {
186
- $url = '/' . ltrim( $url , "/ \t\n\r\0\x0B" );
187
- }
188
- } else {
189
- $url = preg_replace( '#^\w+://#', $scheme . '://', $url );
190
- }
191
-
192
- /**
193
- * Filter the resulting URL after setting the scheme.
194
- *
195
- * @since 3.4.0
196
- *
197
- * @param string $url The complete URL including scheme and path.
198
- * @param string $scheme Scheme applied to the URL. One of 'http', 'https', or 'relative'.
199
- * @param string $orig_scheme Scheme requested for the URL. One of 'http', 'https', 'login',
200
- * 'login_post', 'admin', 'rpc', or 'relative'.
201
- */
202
- return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );
203
- }
204
- endif;
205
-
206
-
207
- // !get_home_path() like. But this time we don't "fallback" to the real function if it exists, because of a bug with old versions.
208
-
209
- function sfml_get_home_path() {
210
- $home = set_url_scheme( get_option( 'home' ), 'http' );
211
- $siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' );
212
-
213
- if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
214
- $wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
215
- $pos = strripos( str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) );
216
- $home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos );
217
- $home_path = trailingslashit( $home_path );
218
- } else {
219
- $home_path = ABSPATH;
220
- }
221
-
222
- return str_replace( '\\', '/', $home_path );
223
- }
224
-
225
-
226
- // !Format un slug with no heading slash and a slash at the end.
227
- // If the slug is empty, it returns an empty string, not a lonely slash.
228
-
229
- function sfml_trailingslash_only( $slug ) {
230
- return ltrim( trim( $slug, '/' ) . '/', '/' );
231
- }
232
-
233
-
234
- // !Has WP its own directory? See http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
235
-
236
- function sfml_wp_directory() {
237
- static $wp_siteurl_subdir;
238
-
239
- if ( ! isset( $wp_siteurl_subdir ) ) {
240
- $wp_siteurl_subdir = '';
241
-
242
- $home = set_url_scheme( rtrim( get_option( 'home' ), '/' ), 'http' );
243
- $siteurl = set_url_scheme( rtrim( get_option( 'siteurl' ), '/' ), 'http' );
244
-
245
- if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
246
- $wp_siteurl_subdir = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
247
- $wp_siteurl_subdir = sfml_trailingslash_only( $wp_siteurl_subdir );
248
- }
249
- }
250
-
251
- return $wp_siteurl_subdir;
252
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/sf-move-login-fr_FR.mo CHANGED
Binary file
languages/sf-move-login-fr_FR.po CHANGED
@@ -2,108 +2,208 @@
2
  #
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: sf-move-login 2.2.3\n"
6
- "Report-msgid -Bugs-To: Grégory Viguier <i18n@screenfeed.fr>\n"
7
- "POT-Creation-Date: 2013-06-01 00:04+0100\n"
8
- "PO-Revision-Date: 2016-04-04 02:57+0200\n"
9
- "Last-Translator: Grégory Viguier <i18n@screenfeed.fr>\n"
10
- "Language-Team: fr_FR\n"
 
11
  "MIME-Version: 1.0\n"
12
  "Content-Type: text/plain; charset=utf-8\n"
13
  "Content-Transfer-Encoding: 8bit\n"
14
- "Plural-Forms: nplurals=2; plural=n>1;\n"
15
- "X-Poedit-SourceCharset: utf-8\n"
16
- "X-Poedit-KeywordsList: __;_e;_n\n"
17
- "Language: fr_FR\n"
18
- "X-Generator: Poedit 1.8.7\n"
19
-
20
- msgid "Change your login URL for something like <code>http://example.com/login</code> and stop login brute force attempts."
21
- msgstr "Changez l&rsquo;url de votre page de connexion pour quelque chose comme <code>http://example.com/login</code> et stoppez les tentatives de connexion par brute force."
22
-
23
- # ---------------------------------------------------------------------------
24
- # sf-move-login.php
25
- msgid "Change your login URL."
26
- msgstr "Changez l&rsquo;url de votre page de connexion."
27
-
28
- # ---------------------------------------------------------------------------
29
- # inc/activate.php
30
  msgid "<strong>Move Login</strong> has not been activated."
31
  msgstr "<strong>Move Login</strong> n&rsquo;a pas été activé."
32
 
33
- msgid "It seems your server configuration prevent the plugin to work properly. <strong>Move Login</strong> won't work."
34
- msgstr "Il semble que votre configuration serveur empêche l&rsquo;extension de fonctionner correctement. <strong>Move Login</strong> ne pourra pas fonctionner."
 
35
 
36
- msgid "It seems the url rewrite module is not activated on your server. <strong>Move Login</strong> won't work."
37
- msgstr "Il semble que le module de réécriture d&rsquo;url n&rsquo;est pas activé sur votre serveur. <strong>Move Login</strong> ne pourra pas fonctionner."
 
 
 
 
 
 
38
 
39
- msgid "It seems your server does not use <i>Apache</i>, <i>Nginx</i>, nor <i>IIS7</i>. <strong>Move Login</strong> won't work."
40
- msgstr "Il semble que votre serveur n&rsquo;utilise ni <i>Apache</i>, <i>Nginx</i>, ou <i>IIS7</i>. <strong>Move Login</strong> ne pourra pas fonctionner."
 
 
 
 
 
41
 
42
- msgid "<strong>Move Login</strong> needs access to the %1$s file. Please visit the %2$s settings page and copy/paste the given code into the %1$s file."
43
- msgstr "<strong>Move Login</strong> a besoin d&rsquo;accéder au fichier %1$s. Veuillez vous rendre sur la page de réglages de %2$s et veuillez copier/coller le code fourni dans le fichier %1$s."
 
 
 
 
 
44
 
45
- msgid "It seems your server uses a <i>Nginx</i> system. You have to edit the rewrite rules by yourself in the configuration file. Please visit the %s settings page and take a look at the rewrite rules. <strong>Move Login</strong> is running but won't work correctly until you deal with those rewrite rules."
46
- msgstr "Il semble que votre serveur utilise un système <i>Nginx</i>. Vous devez éditer les règles de réécriture par vous-même dans le fichier de configuration. Veuillez vous rendre sur la page de réglages de %s et jetez un œil aux règles de réécriture. <strong>Move Login</strong> fonctionne mais ne pourra pas le faire correctement tant que vous ne vous serez pas occupé de ces règles."
 
 
 
 
 
 
 
 
47
 
48
- # ---------------------------------------------------------------------------
49
- # inc/class-sfml-options.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  msgid "The slug %s is forbidden."
51
  msgid_plural "The slugs %s are forbidden."
52
  msgstr[0] "L&rsquo;identifiant %s est interdit."
53
  msgstr[1] "Les identifiants %s sont interdits."
54
 
 
55
  msgid "The links can't have the same slugs."
56
  msgstr "Les liens ne peuvent pas avoir les mêmes identifiants."
57
 
58
- # ---------------------------------------------------------------------------
59
- # inc/redirections-and-dies.php
60
- msgid "No no no, the login form is not here."
61
- msgstr "Non non non, le formulaire de connexion ne se trouve pas ici."
62
-
63
- msgid "Nope :)"
64
- msgstr "Raté :)"
65
 
66
- # ---------------------------------------------------------------------------
67
- # inc/settings-page.php
68
  msgid "Access"
69
  msgstr "Accès"
70
 
 
71
  msgid "Only lowercase letters, digits, - and _"
72
  msgstr "Seulement des lettres minuscules, chiffres, - et _"
73
 
 
74
  msgid "Display an error message"
75
  msgstr "Afficher un message d'erreur"
76
 
 
77
  msgid "Redirect to a &laquo;Page not found&raquo; error page"
78
- msgstr "Rediriger vers une page d&rsquo;erreur &laquo;&#160;Page non trouvée&#160;&raquo;"
 
 
79
 
 
80
  msgid "Redirect to the home page"
81
  msgstr "Rediriger vers la page d&rsquo;accueil"
82
 
 
83
  msgid "When a not connected user attempts to access the old login page."
84
- msgstr "Lorsqu&rsquo;un utilisateur non connecté tente d&rsquo;accéder à l&rsquo;ancienne page de connexion."
 
 
85
 
 
86
  msgid "Administration area"
87
  msgstr "Zone d'administration"
88
 
 
89
  msgid "Do nothing, redirect to the new login page (not recommended)"
90
- msgstr "Ne rien faire, rediriger vers la nouvelle page de connexion (non recommandé)"
 
91
 
 
92
  msgid "When a not connected user attempts to access the administration area."
93
- msgstr "Lorsqu&rsquo;un utilisateur non connecté tente d&rsquo;accéder à la zone d&rsquo;administration."
 
 
94
 
 
 
 
95
  msgctxt "default value"
96
  msgid "(default: %s)"
97
  msgstr "(défaut&#160;: %s)"
98
 
99
- msgid "If the plugin fails to add the new rewrite rules to your %1$s file, add the following to your %1$s file in %2$s, replacing other %3$s rules if they exist, <strong>above</strong> the line reading %4$s:"
100
- msgstr "Si l&rsquo;extension ne peut ajouter les nouvelles règles de réécriture à votre fichier %1$s, ajoutez les lignes suivantes à votre fichier %1$s dans %2$s, en remplacement des autres règles liées à %3$s si elles existent, <strong>au-dessus</strong> de la ligne %4$s&#160;:"
101
-
102
- msgid "The plugin can't add the new rewrite rules to your %s file by itself, you will need to add them manually."
103
- msgstr "L&rsquo;extension ne peut ajouter les nouvelles règles de réécriture à votre fichier %s, vous devrez les ajouter vous-même."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
 
 
 
105
  msgid "Your %s file is not writable."
106
  msgstr "Votre fichier %s n&rsquo;est pas inscriptible."
107
 
108
- msgid "The constant <code>SFML_ALLOW_LOGIN_ACCESS</code> is defined to <code>true</code>, the settings below won't take effect."
109
- msgstr "La constante <code>SFML_ALLOW_LOGIN_ACCESS</code> est définie à <code>true</code>, les réglages ci-dessous ne prendront pas effet."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  #
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Move Login 2.4\n"
6
+ "Report-Msgid-Bugs-To: Grégory Viguier <i18n@screenfeed.fr>\n"
7
+ "POT-Creation-Date: 2017-01-02 23:19+0100\n"
8
+ "PO-Revision-Date: 2017-01-02 23:50+0100\n"
9
+ "Last-Translator: WP Media <contact@secupress.me>\n"
10
+ "Language-Team: French (France)\n"
11
+ "Language: fr_FR\n"
12
  "MIME-Version: 1.0\n"
13
  "Content-Type: text/plain; charset=utf-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
+ "Plural-Forms: nplurals=2; plural=(n > 1);\n"
16
+ "X-Generator: Poedit 1.8.11\n"
17
+ "X-Poedit-Basepath: ..\n"
18
+ "X-Poedit-KeywordsList: _x:1,2c;__;_e;_ex:1,2c;_n:1,2;_nx:1,2;esc_html__;"
19
+ "esc_html_e;_n_noop:1,2\n"
20
+ "X-Poedit-SourceCharset: UTF-8\n"
21
+ "X-Textdomain-Support: yes\n"
22
+ "X-Poedit-SearchPath-0: .\n"
23
+
24
+ #: inc/activate.php:52
 
 
 
 
 
 
25
  msgid "<strong>Move Login</strong> has not been activated."
26
  msgstr "<strong>Move Login</strong> n&rsquo;a pas été activé."
27
 
28
+ #: inc/activate.php:54
29
+ msgid "Error"
30
+ msgstr "Erreur"
31
 
32
+ #: inc/activate.php:114
33
+ msgid ""
34
+ "It seems your server configuration prevent the plugin to work properly. "
35
+ "<strong>Move Login</strong> won't work."
36
+ msgstr ""
37
+ "Il semble que votre configuration serveur empêche l&rsquo;extension de "
38
+ "fonctionner correctement. <strong>Move Login</strong> ne pourra pas "
39
+ "fonctionner."
40
 
41
+ #: inc/activate.php:115
42
+ msgid ""
43
+ "It seems the url rewrite module is not activated on your server. "
44
+ "<strong>Move Login</strong> won't work."
45
+ msgstr ""
46
+ "Il semble que le module de réécriture d&rsquo;url n&rsquo;est pas activé sur "
47
+ "votre serveur. <strong>Move Login</strong> ne pourra pas fonctionner."
48
 
49
+ #: inc/activate.php:116
50
+ msgid ""
51
+ "It seems your server does not use <i>Apache</i>, <i>Nginx</i>, nor <i>IIS7</"
52
+ "i>. <strong>Move Login</strong> won't work."
53
+ msgstr ""
54
+ "Il semble que votre serveur n&rsquo;utilise ni <i>Apache</i>, <i>Nginx</i>, "
55
+ "ou <i>IIS7</i>. <strong>Move Login</strong> ne pourra pas fonctionner."
56
 
57
+ #. Translators: 1 is a file name, 2 is a "Move Login" link.
58
+ #: inc/activate.php:118
59
+ #, php-format
60
+ msgid ""
61
+ "<strong>Move Login</strong> needs access to the %1$s file. Please visit the "
62
+ "%2$s settings page and copy/paste the given code into the %1$s file."
63
+ msgstr ""
64
+ "<strong>Move Login</strong> a besoin d&rsquo;accéder au fichier %1$s. "
65
+ "Veuillez vous rendre sur la page de réglages de %2$s et veuillez copier/"
66
+ "coller le code fourni dans le fichier %1$s."
67
 
68
+ #. Translators: %s is a "Move Login" link.
69
+ #: inc/activate.php:120
70
+ #, php-format
71
+ msgid ""
72
+ "It seems your server uses a <i>Nginx</i> system. You have to edit the "
73
+ "rewrite rules by yourself in the configuration file. Please visit the %s "
74
+ "settings page and take a look at the rewrite rules. <strong>Move Login</"
75
+ "strong> is running but won't work correctly until you deal with those "
76
+ "rewrite rules."
77
+ msgstr ""
78
+ "Il semble que votre serveur utilise un système <i>Nginx</i>. Vous devez "
79
+ "éditer les règles de réécriture par vous-même dans le fichier de "
80
+ "configuration. Veuillez vous rendre sur la page de réglages de %s et jetez "
81
+ "un œil aux règles de réécriture. <strong>Move Login</strong> fonctionne mais "
82
+ "ne pourra pas le faire correctement tant que vous ne vous serez pas occupé "
83
+ "de ces règles."
84
+
85
+ #. Translators: %s is an URL slug name.
86
+ #: inc/classes/class-sfml-options.php:389
87
+ #, php-format
88
  msgid "The slug %s is forbidden."
89
  msgid_plural "The slugs %s are forbidden."
90
  msgstr[0] "L&rsquo;identifiant %s est interdit."
91
  msgstr[1] "Les identifiants %s sont interdits."
92
 
93
+ #: inc/classes/class-sfml-options.php:392
94
  msgid "The links can't have the same slugs."
95
  msgstr "Les liens ne peuvent pas avoir les mêmes identifiants."
96
 
97
+ #: inc/functions/settings-page.php:19
98
+ msgid "Choose your new URLs"
99
+ msgstr "Choisissez vos nouvelles adresses"
 
 
 
 
100
 
101
+ #: inc/functions/settings-page.php:20
 
102
  msgid "Access"
103
  msgstr "Accès"
104
 
105
+ #: inc/functions/settings-page.php:42
106
  msgid "Only lowercase letters, digits, - and _"
107
  msgstr "Seulement des lettres minuscules, chiffres, - et _"
108
 
109
+ #: inc/functions/settings-page.php:60 inc/functions/settings-page.php:81
110
  msgid "Display an error message"
111
  msgstr "Afficher un message d'erreur"
112
 
113
+ #: inc/functions/settings-page.php:61 inc/functions/settings-page.php:82
114
  msgid "Redirect to a &laquo;Page not found&raquo; error page"
115
+ msgstr ""
116
+ "Rediriger vers une page d&rsquo;erreur &laquo;&#160;Page non trouvée&#160;"
117
+ "&raquo;"
118
 
119
+ #: inc/functions/settings-page.php:62 inc/functions/settings-page.php:83
120
  msgid "Redirect to the home page"
121
  msgstr "Rediriger vers la page d&rsquo;accueil"
122
 
123
+ #: inc/functions/settings-page.php:64
124
  msgid "When a not connected user attempts to access the old login page."
125
+ msgstr ""
126
+ "Lorsqu&rsquo;un utilisateur non connecté tente d&rsquo;accéder à l&rsquo;"
127
+ "ancienne page de connexion."
128
 
129
+ #: inc/functions/settings-page.php:71
130
  msgid "Administration area"
131
  msgstr "Zone d'administration"
132
 
133
+ #: inc/functions/settings-page.php:80
134
  msgid "Do nothing, redirect to the new login page (not recommended)"
135
+ msgstr ""
136
+ "Ne rien faire, rediriger vers la nouvelle page de connexion (non recommandé)"
137
 
138
+ #: inc/functions/settings-page.php:85
139
  msgid "When a not connected user attempts to access the administration area."
140
+ msgstr ""
141
+ "Lorsqu&rsquo;un utilisateur non connecté tente d&rsquo;accéder à la zone "
142
+ "d&rsquo;administration."
143
 
144
+ #. Translators: %s is an option value.
145
+ #: inc/functions/settings-page.php:167 inc/functions/settings-page.php:210
146
+ #, php-format
147
  msgctxt "default value"
148
  msgid "(default: %s)"
149
  msgstr "(défaut&#160;: %s)"
150
 
151
+ #. Translators: 1 is a file name, 2 is a file path, 3 and 4 are small parts of code.
152
+ #: inc/functions/settings-page.php:240 inc/functions/settings-page.php:272
153
+ #, php-format
154
+ msgid ""
155
+ "If the plugin fails to add the new rewrite rules to your %1$s file, add the "
156
+ "following to your %1$s file in %2$s, replacing other %3$s rules if they "
157
+ "exist, <strong>above</strong> the line reading %4$s:"
158
+ msgstr ""
159
+ "Si l&rsquo;extension ne peut ajouter les nouvelles règles de réécriture à "
160
+ "votre fichier %1$s, ajoutez les lignes suivantes à votre fichier %1$s dans "
161
+ "%2$s, en remplacement des autres règles liées à %3$s si elles existent, "
162
+ "<strong>au-dessus</strong> de la ligne %4$s&#160;:"
163
+
164
+ #. Translators: 1 is a file name, 2 is a small part of code.
165
+ #: inc/functions/settings-page.php:255
166
+ #, php-format
167
+ msgid ""
168
+ "The plugin can't add the new rewrite rules to your %1$s file by itself, you "
169
+ "will need to add them manually inside the %2$s block."
170
+ msgstr ""
171
+ "L&rsquo;extension ne peut ajouter les nouvelles règles de réécriture à votre "
172
+ "fichier %1$s, vous devrez les ajouter manuellement à l&rsquo;intérieur du "
173
+ "bloc %2$s."
174
 
175
+ #. Translators: %s is a file name.
176
+ #: inc/functions/settings-page.php:288
177
+ #, php-format
178
  msgid "Your %s file is not writable."
179
  msgstr "Votre fichier %s n&rsquo;est pas inscriptible."
180
 
181
+ #. Translators: 1 is a constant name, 2 is a constant value.
182
+ #: inc/functions/settings-page.php:296
183
+ #, php-format
184
+ msgid ""
185
+ "The constant %1$s is defined to %2$s, the settings below won't take effect."
186
+ msgstr ""
187
+ "La constante %1$s est définie à %2$s, les réglages ci-dessous ne prendront "
188
+ "pas effet."
189
+
190
+ #: inc/redirections-and-dies.php:114
191
+ msgid "No no no, the login form is not here."
192
+ msgstr "Non non non, le formulaire de connexion ne se trouve pas ici."
193
+
194
+ #: inc/redirections-and-dies.php:114 inc/redirections-and-dies.php:192
195
+ msgid "Nope :)"
196
+ msgstr "Raté :)"
197
+
198
+ #. Translators: Description of the plugin/theme
199
+ #: sf-move-login.php:91
200
+ msgid "Change your login URL."
201
+ msgstr "Changez l&rsquo;url de votre page de connexion."
202
+
203
+ #~ msgid ""
204
+ #~ "Change your login URL for something like <code>http://example.com/login</"
205
+ #~ "code> and stop login brute force attempts."
206
+ #~ msgstr ""
207
+ #~ "Changez l&rsquo;url de votre page de connexion pour quelque chose comme "
208
+ #~ "<code>http://example.com/login</code> et stoppez les tentatives de "
209
+ #~ "connexion par brute force."
readme.txt CHANGED
@@ -3,21 +3,23 @@
3
  Contributors: GregLone, SecuPress, juliobox
4
  Tags: login, logout, url, security
5
  Requires at least: 3.1
6
- Tested up to: 4.5
7
  Stable tag: trunk
8
  License: GPLv3
9
  License URI: https://www.screenfeed.fr/gpl-v3.txt
10
 
11
- Change your login URL for something like http://example.com/login and stop login brute-force attempts.
12
 
13
 
14
  == Description ==
15
 
16
- This plugin forbids access to **http://example.com/wp-login.php** and creates new urls, like **http://example.com/login** or **http://example.com/logout**.
17
  This is a great way to limit bots trying to brute-force your login (trying to guess your login and password). Of course, the new URLs are easier to remember too.
18
 
19
  Also remember: the use of this plugin does NOT exempt you to use a strong password. Moreover, never use "admin" as login, this is the first attempt for bots.
20
 
 
 
21
  = Translations =
22
 
23
  * US English
@@ -27,14 +29,14 @@ Also remember: the use of this plugin does NOT exempt you to use a strong passwo
27
 
28
  = Multisite =
29
 
30
- Yep!
31
- The plugin must be activated from your network.
32
- Note 1: this plugin deals only with `wp-login.php`, not with `wp-signup.php` nor with `wp-activate.php` (yet). That means **http://example.com/register** will still redirect to **http://example.com/wp-signup.php**. I think this will be the next step though, but no ETA.
33
- Note 2: if users/sites registrations are open, you shouldn't use this plugin yet. There are some places where the log in address is hard coded and not filterable. A [bug ticket](https://core.trac.wordpress.org/ticket/31495 "Always use 'login' as $scheme parameter for "login-ish" URLs, and other inconsistencies") is open.
34
 
35
  = Requirements =
36
 
37
- * See some important informations in the "Installation" tab (I mean it).
 
38
  * Should work on IIS7+ servers but not tested (I guess you should probably save a copy of your `web.config` file before the plugin activation).
39
  * For Nginx servers, the rewrite rules are not written automatically of course, but they are provided as information in the plugin settings page.
40
 
@@ -43,9 +45,9 @@ Note 2: if users/sites registrations are open, you shouldn't use this plugin yet
43
 
44
  1. Extract the plugin folder from the downloaded ZIP file.
45
  1. Upload the `sf-move-login` folder to your `/wp-content/plugins/` directory.
46
- 1. If you have another plugin that makes redirections to **http://example.com/wp-login.php** (a short-links plugin for example), disable it or remove the redirection, otherwise they will conflict and you'll be locked out. See the FAQ in case you're not able to reach the login page (make sure to have a ftp access to your site).
47
  1. Activate the plugin from the "Plugins" page.
48
- 1. If the plugin can't write your `.htaccess` file or `web.config` file, you'll need to edit it yourself with a ftp access, the rules are provided in the plugin settings page.
49
 
50
 
51
  == Frequently Asked Questions ==
@@ -56,13 +58,13 @@ Since the version 1.1, yes. And since the version 2.0, you don't need any additi
56
 
57
  = I'm locked out! I can't access the login page! =
58
 
59
- You're screwed! No, I'm kidding, but you need a ftp access to your site. When logged in with your ftp software, open the file `wp-config.php` located at the root of your installation. Simply add this in the file: `define( 'SFML_ALLOW_LOGIN_ACCESS', true );` and save the file. This will bypass the plugin and you'll be able to access **http://example.com/wp-login.php**. Another plugin may conflict, you'll need to find which one before removing this new line of code.
60
 
61
  = Does it really work for Multisite? =
62
 
63
  Yes. Each blog has its own login page (but the customized slugs are the same for each blog though). The plugin must be activated from the network.
64
 
65
- Eventually, try the [WordPress support forum](http://wordpress.org/support/plugin/sf-move-login) (best), or check out [my blog](https://www.screenfeed.fr/plugin-wp/move-login/ "Move Login") for more infos, help, or bug reports (sorry guys, it's in French, but feel free to leave a comment in English).
66
 
67
 
68
  == Screenshots ==
@@ -72,6 +74,24 @@ Eventually, try the [WordPress support forum](http://wordpress.org/support/plugi
72
 
73
  == Changelog ==
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  = 2.3 =
76
 
77
  * 2016/04/04
@@ -132,7 +152,7 @@ Eventually, try the [WordPress support forum](http://wordpress.org/support/plugi
132
  = 2.1 =
133
 
134
  * 2015/03/01
135
- * New: Installations where [WordPress has its own directory](http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory "Giving WordPress Its Own Directory") are now supported. (〜 ̄▽ ̄)〜
136
  * New: For multisite, the log in address in the "new site" welcome email is now filtered. Unfortunately there are some other places where the log in address can't be changed, regarding the user/site registration messages. A [bug ticket](https://core.trac.wordpress.org/ticket/31495 "Always use 'login' as $scheme parameter for "login-ish" URLs, and other inconsistencies") is open.
137
  * Improvement: All rewrite rules have been improved. Feedback from Nginx users are welcome (as you may know, I'm a Nginx n00b).
138
  * Improvement: Better handling of `network_site_url()`.
@@ -155,7 +175,7 @@ Eventually, try the [WordPress support forum](http://wordpress.org/support/plugi
155
  * 2015/02/22
156
  * Most of the plugin has been rewritten.
157
  * New: you don't need my framework Noop to have a settings page anymore (yes, you can uninstall it if it's not used elsewhere). ᕙ(⇀‸↼‶)ᕗ The bad news is there are no settings import/export/history anymore (and it won't come back). Make sure your settings are ok after upgrading.
158
- * New: the plugin disable some WordPress native redirections to administration area and login page. For example, **http://example.com/dashboard/** was leading to **http://example.com/wp-admin/**. This should solve a bunch of bugs.
159
  * New: the rewrite rules for Nginx servers are now provided in the plugin settings page as information. Thank you [Milouze](https://wordpress.org/support/topic/for-Nginx-server).
160
  * Improvement: bugfix for IIS servers.
161
  * Improvement: better French translations.
3
  Contributors: GregLone, SecuPress, juliobox
4
  Tags: login, logout, url, security
5
  Requires at least: 3.1
6
+ Tested up to: 4.7.2
7
  Stable tag: trunk
8
  License: GPLv3
9
  License URI: https://www.screenfeed.fr/gpl-v3.txt
10
 
11
+ Change your login URL for something like https://example.com/login and stop login brute-force attempts.
12
 
13
 
14
  == Description ==
15
 
16
+ This plugin forbids access to **https://example.com/wp-login.php** and creates new urls, like **https://example.com/login** or **https://example.com/logout**.
17
  This is a great way to limit bots trying to brute-force your login (trying to guess your login and password). Of course, the new URLs are easier to remember too.
18
 
19
  Also remember: the use of this plugin does NOT exempt you to use a strong password. Moreover, never use "admin" as login, this is the first attempt for bots.
20
 
21
+ By the way, if you are looking for a complete security solution, take a look at [SecuPress](https://wordpress.org/plugins/secupress/): Move Login is included inside.
22
+
23
  = Translations =
24
 
25
  * US English
29
 
30
  = Multisite =
31
 
32
+ Yes! The plugin must be activated from your network.
33
+ **Note 1**: this plugin deals only with `wp-login.php`, not with `wp-signup.php` nor with `wp-activate.php` (yet). That means **https://example.com/register** will still redirect to **https://example.com/wp-signup.php**. I think this will be the next step though, but no ETA.
34
+ **Note 2**: if users/sites registrations are open, you shouldn't use this plugin yet. There are some places where the log in address is hard coded and not filterable. A [bug ticket](https://core.trac.wordpress.org/ticket/31495 "Always use 'login' as $scheme parameter for "login-ish" URLs, and other inconsistencies") is open.
 
35
 
36
  = Requirements =
37
 
38
+ * **PHP 5.3 at least**.
39
+ * You will need a FTP access: if the `.htaccess`/`web.config` file is not writable (you will need to add the given rules manually), or if something is wrong and you can't log in anymore (see the FAQ in that case).
40
  * Should work on IIS7+ servers but not tested (I guess you should probably save a copy of your `web.config` file before the plugin activation).
41
  * For Nginx servers, the rewrite rules are not written automatically of course, but they are provided as information in the plugin settings page.
42
 
45
 
46
  1. Extract the plugin folder from the downloaded ZIP file.
47
  1. Upload the `sf-move-login` folder to your `/wp-content/plugins/` directory.
48
+ 1. If you have another plugin that makes redirections to **https://example.com/wp-login.php** (a short-links plugin for example), disable it or remove the redirection, otherwise they will conflict and you'll be locked out. See the FAQ in case you're not able to reach the login page (make sure to have a FTP access to your site).
49
  1. Activate the plugin from the "Plugins" page.
50
+ 1. If the plugin can't write your `.htaccess` file or `web.config` file, you'll need to edit it yourself with a FTP access, the rules are provided in the plugin settings page.
51
 
52
 
53
  == Frequently Asked Questions ==
58
 
59
  = I'm locked out! I can't access the login page! =
60
 
61
+ You're screwed! No, I'm kidding, but you need a FTP access to your site. When logged in with your FTP software, open the file `wp-config.php` located at the root of your installation. Simply add this in the file: `define( 'SFML_ALLOW_LOGIN_ACCESS', true );` and save the file. This will bypass the plugin and you'll be able to access **https://example.com/wp-login.php**. Another plugin may conflict, you'll need to find which one before removing this new line of code.
62
 
63
  = Does it really work for Multisite? =
64
 
65
  Yes. Each blog has its own login page (but the customized slugs are the same for each blog though). The plugin must be activated from the network.
66
 
67
+ Eventually, try the [WordPress support forum](https://wordpress.org/support/plugin/sf-move-login) (best), or check out [my blog](https://www.screenfeed.fr/plugin-wp/move-login/ "Move Login") for more infos, help, or bug reports (sorry folks, it's in French, but feel free to leave a comment in English).
68
 
69
 
70
  == Screenshots ==
74
 
75
  == Changelog ==
76
 
77
+ = 2.4.2 =
78
+
79
+ * 2017/02/04
80
+ * Fixed a simple PHP warning.
81
+
82
+ = 2.4.1 =
83
+
84
+ * 2017/01/07
85
+ * Added missing test for PHP version :s
86
+
87
+ = 2.4 =
88
+
89
+ * 2017/01/03
90
+ * Move Login now requires PHP 5.3 at least!
91
+ * New: tell cache plugins not to cache the login pages (constant `DONOTCACHEPAGE`).
92
+ * Improved: nginx support should be fine now.
93
+ * I've revamped the plugin with what I've done on SecuPress (lots of things have changed internally).
94
+
95
  = 2.3 =
96
 
97
  * 2016/04/04
152
  = 2.1 =
153
 
154
  * 2015/03/01
155
+ * New: Installations where [WordPress has its own directory](https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory "Giving WordPress Its Own Directory") are now supported. (〜 ̄▽ ̄)〜
156
  * New: For multisite, the log in address in the "new site" welcome email is now filtered. Unfortunately there are some other places where the log in address can't be changed, regarding the user/site registration messages. A [bug ticket](https://core.trac.wordpress.org/ticket/31495 "Always use 'login' as $scheme parameter for "login-ish" URLs, and other inconsistencies") is open.
157
  * Improvement: All rewrite rules have been improved. Feedback from Nginx users are welcome (as you may know, I'm a Nginx n00b).
158
  * Improvement: Better handling of `network_site_url()`.
175
  * 2015/02/22
176
  * Most of the plugin has been rewritten.
177
  * New: you don't need my framework Noop to have a settings page anymore (yes, you can uninstall it if it's not used elsewhere). ᕙ(⇀‸↼‶)ᕗ The bad news is there are no settings import/export/history anymore (and it won't come back). Make sure your settings are ok after upgrading.
178
+ * New: the plugin disable some WordPress native redirections to administration area and login page. For example, **https://example.com/dashboard/** was leading to **https://example.com/wp-admin/**. This should solve a bunch of bugs.
179
  * New: the rewrite rules for Nginx servers are now provided in the plugin settings page as information. Thank you [Milouze](https://wordpress.org/support/topic/for-Nginx-server).
180
  * Improvement: bugfix for IIS servers.
181
  * Improvement: better French translations.
sf-move-login.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
- /*
3
  * Plugin Name: SF Move Login
4
  * Plugin URI: https://www.screenfeed.fr/plugin-wp/move-login/
5
  * Description: Change your login URL.
6
- * Version: 2.3
7
  * Author: Grégory Viguier
8
  * Author URI: https://www.screenfeed.fr/
9
  * License: GPLv3
@@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
17
  die( 'Cheatin\' uh?' );
18
  }
19
 
20
- if ( version_compare( $GLOBALS['wp_version'], '3.1', '<' ) ) {
21
  return;
22
  }
23
 
@@ -25,7 +25,7 @@ if ( version_compare( $GLOBALS['wp_version'], '3.1', '<' ) ) {
25
  /* !CONSTANTS =================================================================================== */
26
  /*------------------------------------------------------------------------------------------------*/
27
 
28
- define( 'SFML_VERSION', '2.3' );
29
  define( 'SFML_FILE', __FILE__ );
30
  define( 'SFML_PLUGIN_BASENAME', plugin_basename( SFML_FILE ) );
31
  define( 'SFML_PLUGIN_DIR', plugin_dir_path( SFML_FILE ) );
@@ -35,26 +35,35 @@ define( 'SFML_PLUGIN_DIR', plugin_dir_path( SFML_FILE ) );
35
  /* !INCLUDES ==================================================================================== */
36
  /*------------------------------------------------------------------------------------------------*/
37
 
38
- add_action( 'after_setup_theme', 'sfml_init', 11 );
 
 
 
39
 
40
- function sfml_init() {
41
- include( SFML_PLUGIN_DIR . 'inc/utilities.php' );
 
42
 
43
- if ( ! class_exists( 'SFML_Options' ) ) {
44
- include( SFML_PLUGIN_DIR . 'inc/class-sfml-options.php' );
45
- SFML_Options::init();
46
- }
47
 
48
- // Administration
 
 
 
 
 
 
 
49
  if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
50
- include( SFML_PLUGIN_DIR . 'inc/admin.php' );
51
  }
52
 
53
- // !EMERGENCY BYPASS
54
- if ( ! defined( 'SFML_ALLOW_LOGIN_ACCESS' ) || ! SFML_ALLOW_LOGIN_ACCESS ) {
55
- include( SFML_PLUGIN_DIR . 'inc/url-filters.php' );
56
- include( SFML_PLUGIN_DIR . 'inc/redirections-and-dies.php' );
57
  }
 
 
 
58
  }
59
 
60
 
@@ -63,16 +72,21 @@ function sfml_init() {
63
  /*------------------------------------------------------------------------------------------------*/
64
 
65
  add_action( 'init', 'sfml_lang_init' );
66
-
 
 
67
  function sfml_lang_init() {
68
- load_plugin_textdomain( 'sf-move-login', false, basename( dirname( SFML_FILE ) ) . '/languages' );
69
- }
 
 
 
70
 
 
71
 
72
- /*------------------------------------------------------------------------------------------------*/
73
- /* !PLUGIN ACTIVATION AND DEACTIVATION ========================================================== */
74
- /*------------------------------------------------------------------------------------------------*/
75
 
76
- if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
77
- include( SFML_PLUGIN_DIR . 'inc/activate.php' );
 
78
  }
1
  <?php
2
+ /**
3
  * Plugin Name: SF Move Login
4
  * Plugin URI: https://www.screenfeed.fr/plugin-wp/move-login/
5
  * Description: Change your login URL.
6
+ * Version: 2.4.2
7
  * Author: Grégory Viguier
8
  * Author URI: https://www.screenfeed.fr/
9
  * License: GPLv3
17
  die( 'Cheatin\' uh?' );
18
  }
19
 
20
+ if ( empty( $GLOBALS['wp_version'] ) || version_compare( $GLOBALS['wp_version'], '3.1' ) < 0 || version_compare( phpversion(), '5.3' ) < 0 ) {
21
  return;
22
  }
23
 
25
  /* !CONSTANTS =================================================================================== */
26
  /*------------------------------------------------------------------------------------------------*/
27
 
28
+ define( 'SFML_VERSION', '2.4.2' );
29
  define( 'SFML_FILE', __FILE__ );
30
  define( 'SFML_PLUGIN_BASENAME', plugin_basename( SFML_FILE ) );
31
  define( 'SFML_PLUGIN_DIR', plugin_dir_path( SFML_FILE ) );
35
  /* !INCLUDES ==================================================================================== */
36
  /*------------------------------------------------------------------------------------------------*/
37
 
38
+ include( SFML_PLUGIN_DIR . 'inc/functions/compat.php' );
39
+ include( SFML_PLUGIN_DIR . 'inc/functions/utilities.php' );
40
+ include( SFML_PLUGIN_DIR . 'inc/classes/class-sfml-singleton.php' );
41
+ include( SFML_PLUGIN_DIR . 'inc/classes/class-sfml-options.php' );
42
 
43
+ if ( is_admin() ) {
44
+ include( SFML_PLUGIN_DIR . 'inc/activate.php' );
45
+ }
46
 
 
 
 
 
47
 
48
+ add_action( 'plugins_loaded', 'sfml_init', 20 );
49
+ /**
50
+ * Plugin init: include files.
51
+ */
52
+ function sfml_init() {
53
+ SFML_Options::get_instance();
54
+
55
+ // Administration.
56
  if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
57
+ include_once( SFML_PLUGIN_DIR . 'inc/admin.php' );
58
  }
59
 
60
+ // !EMERGENCY BYPASS.
61
+ if ( defined( 'SFML_ALLOW_LOGIN_ACCESS' ) && SFML_ALLOW_LOGIN_ACCESS ) {
62
+ return;
 
63
  }
64
+
65
+ include_once( SFML_PLUGIN_DIR . 'inc/url-filters.php' );
66
+ include_once( SFML_PLUGIN_DIR . 'inc/redirections-and-dies.php' );
67
  }
68
 
69
 
72
  /*------------------------------------------------------------------------------------------------*/
73
 
74
  add_action( 'init', 'sfml_lang_init' );
75
+ /**
76
+ * Load translations.
77
+ */
78
  function sfml_lang_init() {
79
+ static $done = false;
80
+
81
+ if ( $done ) {
82
+ return;
83
+ }
84
 
85
+ $done = true;
86
 
87
+ load_plugin_textdomain( 'sf-move-login', false, dirname( plugin_basename( SFML_FILE ) ) . '/languages' );
 
 
88
 
89
+ // Make sure Poedit keeps our plugin headers.
90
+ /** Translators: Description of the plugin/theme */
91
+ __( 'Change your login URL.', 'sf-move-login' );
92
  }
uninstall.php CHANGED
@@ -4,7 +4,7 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
4
  }
5
 
6
 
7
- include( plugin_dir_path( __FILE__ ) . 'inc/class-sfml-options.php' );
8
 
9
  delete_site_option( 'sfml_version' );
10
  delete_site_option( SFML_Options::OPTION_NAME );
4
  }
5
 
6
 
7
+ include_once( plugin_dir_path( __FILE__ ) . 'inc/class-sfml-options.php' );
8
 
9
  delete_site_option( 'sfml_version' );
10
  delete_site_option( SFML_Options::OPTION_NAME );