Move Login - Version 2.3

Version Description

  • 2016/04/04
  • Tested with WP 4.5.
  • Code quality improvements.
  • Fixed a notice with php7.
  • Mark the option "Do nothing, redirect to the new login page" as not recommended.
  • If not logged in, deny access to wp-signup.php and wp-register.php (mono-site installations).
  • When blocking access, use a 501 error code instead of 500.
  • Added compatibility with websites that are not using port 80 and 443.
Download this release

Release Info

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

Code changes from version 0.1 to 2.3

inc/activate.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
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
+ }
inc/admin.php ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ 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;
111
+ }
112
+
113
+
114
+ /*------------------------------------------------------------------------------------------------*/
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';
123
+ add_submenu_page( $page, 'Move Login', 'Move Login', $cap, SFML_Options::OPTION_PAGE, 'sfml_settings_page' );
124
+ }
125
+
126
+
127
+ /*------------------------------------------------------------------------------------------------*/
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
+
140
+ /*------------------------------------------------------------------------------------------------*/
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
+
153
+ if ( ! isset( $_POST['option_page'] ) || $_POST['option_page'] !== $option_group ) { // WPCS: CSRF ok.
154
+ return;
155
+ }
156
+
157
+ $capability = apply_filters( "option_page_capability_{$option_group}", 'manage_network_options' );
158
+
159
+ if ( ! current_user_can( $capability ) ) {
160
+ wp_die( __( 'Cheatin&#8217; uh?' ), 403 );
161
+ }
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.' ) );
169
+ }
170
+
171
+ $options = $whitelist_options[ $option_group ];
172
+
173
+ if ( $options ) {
174
+ foreach ( $options as $option ) {
175
+ $option = trim( $option );
176
+ $value = null;
177
+
178
+ if ( isset( $_POST[ $option ] ) ) {
179
+ $value = $_POST[ $option ];
180
+ if ( ! is_array( $value ) ) {
181
+ $value = trim( $value );
182
+ }
183
+ $value = wp_unslash( $value );
184
+ }
185
+
186
+ update_site_option( $option, $value );
187
+ }
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() ) ) {
195
+ add_settings_error( 'general', 'settings_updated', __( 'Settings saved.' ), 'updated' );
196
+ }
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
+
207
+ endif;
208
+
209
+
210
+ /*------------------------------------------------------------------------------------------------*/
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 );
229
+ delete_metadata( 'user', 0, 'closedpostboxes_' . $page_parent_name . '_page_' . $page_name, null, true );
230
+
231
+ if ( is_multisite() ) {
232
+ delete_metadata( 'user', 0, 'screen_layout_' . $page_parent_name . '_page_' . $page_name . '-network', null, true );
233
+ delete_metadata( 'user', 0, 'metaboxhidden_' . $page_parent_name . '_page_' . $page_name . '-network', null, true );
234
+ delete_metadata( 'user', 0, 'meta-box-order_' . $page_parent_name . '_page_' . $page_name . '-network', null, true );
235
+ delete_metadata( 'user', 0, 'closedpostboxes_' . $page_parent_name . '_page_' . $page_name . '-network', null, true );
236
+ }
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;
252
+
253
+ if ( $db_version ) {
254
+ $mono_or_multi = isset( $db_version[1] ) ? (int) $db_version[1] : 0;
255
+ $db_version = $db_version[0];
256
+ }
257
+
258
+ // We're right on track.
259
+ if ( $db_version && 0 === version_compare( $db_version, SFML_VERSION ) && $mono_or_multi === $current_mono_multi ) {
260
+ return;
261
+ }
262
+
263
+ // Try to get a version from an older version, but only for multisite because on non-multisites get_site_option() and get_option() are the same.
264
+ if ( ! $db_version && is_multisite() ) {
265
+ $db_version = get_option( 'sfml_version' );
266
+ delete_option( 'sfml_version' );
267
+ }
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();
282
+ } else {
283
+ $old_options = get_option( 'sfml' );
284
+ sfml_delete_noop_options();
285
+ }
286
+
287
+ // Noop stores the options separately, by language, whether you use a multilingual site or not.
288
+ $old_options = is_array( $old_options ) && ! isset( $old_options['slugs.login'] ) ? reset( $old_options ) : $old_options;
289
+ $old_options = is_array( $old_options ) ? $old_options : array();
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 ) {
308
+ $old_options = sfml_get_options();
309
+ update_site_option( SFML_Options::OPTION_NAME, $old_options );
310
+ $update_file = '2';
311
+ }
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 );
319
+ }
320
+
321
+ sfml_upgrade();
322
+
323
+
324
+ /*------------------------------------------------------------------------------------------------*/
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
+
371
+ foreach ( $notices as $notice ) {
372
+ $index = substr( $notice, 0, strpos( $notice, '_' ) );
373
+ $messages[ $index ][] = sfml_notice_message( $notice );
374
+ }
375
+
376
+ $messages = array_filter( array_map( 'array_filter', $messages ) );
377
+
378
+ foreach ( $messages as $class => $message ) {
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
+ }
inc/class-sfml-options.php ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/redirections-and-dies.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
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;
76
+ }
77
+ if ( false === strpos( $_SERVER['REQUEST_URI'], '/wp-signup.php' ) && false === strpos( $_SERVER['REQUEST_URI'], '/wp-register.php' ) ) {
78
+ return $url;
79
+ }
80
+ if ( is_multisite() || is_user_logged_in() ) {
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
+ }
inc/rewrite.php ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/settings-page.php ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
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,
31
+ 'sfml_text_field',
32
+ SFML_Options::OPTION_PAGE,
33
+ 'slugs',
34
+ array(
35
+ 'label_for' => 'slugs-' . $slug,
36
+ 'name' => 'slugs.' . $slug,
37
+ 'value' => $options[ 'slugs.' . $slug ],
38
+ 'default' => $slug,
39
+ 'attributes' => array(
40
+ 'pattern' => '[0-9a-z_-]*',
41
+ 'title' => __( 'Only lowercase letters, digits, - and _', 'sf-move-login' ),
42
+ ),
43
+ )
44
+ );
45
+ }
46
+
47
+ // Deny access to login form.
48
+ add_settings_field(
49
+ 'deny_wp_login_access',
50
+ '<code>wp-login.php</code>',
51
+ 'sfml_radio_field',
52
+ SFML_Options::OPTION_PAGE,
53
+ 'access',
54
+ array(
55
+ 'label_for' => 'deny_wp_login_access',
56
+ 'value' => $options['deny_wp_login_access'],
57
+ 'default' => $defaults['deny_wp_login_access'],
58
+ 'values' => array(
59
+ 1 => __( 'Display an error message', 'sf-move-login' ),
60
+ 2 => __( 'Redirect to a &laquo;Page not found&raquo; error page', 'sf-move-login' ),
61
+ 3 => __( 'Redirect to the home page', 'sf-move-login' ),
62
+ ),
63
+ 'label' => '<strong>' . __( 'When a not connected user attempts to access the old login page.', 'sf-move-login' ) . '</strong>',
64
+ )
65
+ );
66
+
67
+ // Deny access to admin area.
68
+ add_settings_field(
69
+ 'deny_admin_access',
70
+ __( 'Administration area', 'sf-move-login' ),
71
+ 'sfml_radio_field',
72
+ SFML_Options::OPTION_PAGE,
73
+ 'access',
74
+ array(
75
+ 'label_for' => 'deny_admin_access',
76
+ 'value' => $options['deny_admin_access'],
77
+ 'default' => $defaults['deny_admin_access'],
78
+ 'values' => array(
79
+ 0 => __( 'Do nothing, redirect to the new login page (not recommended)', 'sf-move-login' ),
80
+ 1 => __( 'Display an error message', 'sf-move-login' ),
81
+ 2 => __( 'Redirect to a &laquo;Page not found&raquo; error page', 'sf-move-login' ),
82
+ 3 => __( 'Redirect to the home page', 'sf-move-login' ),
83
+ ),
84
+ 'label' => '<strong>' . __( 'When a not connected user attempts to access the administration area.', 'sf-move-login' ) . '</strong>',
85
+ )
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.
105
+ $parent_file .= '#sfml';
106
+ }
107
+
108
+
109
+ // !The settings page
110
+
111
+ function sfml_settings_page() {
112
+ global $wp_version;
113
+ ?>
114
+ <div class="wrap">
115
+ <?php
116
+ // WordPress 4.3 uses a `<h1>` tag, not a `<h2>` anymore. In the same time, get rid of the old icon.
117
+ if ( version_compare( $wp_version, '4.3-RC1' ) >= 0 ) {
118
+ echo '<h1>Move Login</h1>';
119
+ } else {
120
+ screen_icon( 'tools' );
121
+ echo '<h2>Move Login</h2>';
122
+ }
123
+
124
+ require( ABSPATH . 'wp-admin/options-head.php' ); ?>
125
+
126
+ <form name="<?php echo SFML_Options::OPTION_PAGE ?>" method="post" action="<?php echo esc_url( is_multisite() ? admin_url( 'admin-post.php' ) : admin_url( 'options.php' ) ); ?>" id="<?php echo SFML_Options::OPTION_PAGE ?>">
127
+ <?php
128
+ do_settings_sections( SFML_Options::OPTION_PAGE );
129
+ settings_fields( SFML_Options::OPTION_GROUP );
130
+ submit_button();
131
+ ?>
132
+ </form>
133
+
134
+ <?php sfml_rewrite_rules_textarea(); ?>
135
+ </div>
136
+ <?php
137
+ }
138
+
139
+
140
+ /*------------------------------------------------------------------------------------------------*/
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;
155
+ }
156
+
157
+ printf(
158
+ '<input type="text" name="%s"%s%s value="%s"/>',
159
+ SFML_Options::OPTION_NAME . '[' . $name . ']',
160
+ $id ? ' id="' . $id . '"' : '',
161
+ $atts,
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;
176
+ $value = isset( $args['value'] ) ? $args['value'] : '';
177
+ $values = isset( $args['values'] ) ? $args['values'] : false;
178
+ $default = isset( $args['default'] ) ? $args['default'] : null;
179
+ $label = isset( $args['label'] ) ? $args['label'] : '';
180
+
181
+ if ( ! $name || ! $values || ! is_array( $values ) ) {
182
+ return;
183
+ }
184
+
185
+ if ( ! is_null( $default ) && ! isset( $values[ $value ] ) ) {
186
+ $value = $default;
187
+ }
188
+
189
+ $i = 0;
190
+ echo $label ? '<label for="' . $id . '">' . $label . '</label><br/>' : '';
191
+
192
+ foreach ( $values as $input_value => $input_label ) {
193
+ printf(
194
+ '<input type="radio" name="%s" id="%s"%s value="%s"/>',
195
+ SFML_Options::OPTION_NAME . '[' . $name . ']',
196
+ $id . ( $i ? '-' . $i : '' ),
197
+ $input_value === $value ? ' checked="checked"' : '',
198
+ esc_attr( $input_value )
199
+ );
200
+ echo '<label for="' . $id . ( $i ? '-' . $i : '' ) . '">' . $input_label . '</label><br/>';
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";
255
+ $file_content .= implode( "\n", sfml_apache_rewrite_rules( $rules ) );
256
+ $file_content .= "\n# END SF Move Login\n";
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.
265
+ else {
266
+ return;
267
+ }
268
+
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";
283
+ $content .= '<textarea id="sfml-file-content" class="code readonly hide-if-js" readonly="readonly" cols="120" rows="' . $height . '">' . esc_textarea( $file_content ) . "</textarea>\n";
284
+ $content .= '<script type="text/javascript">jQuery( "#sfml-file-button" ).on( "click", function() { jQuery( this ).remove(); jQuery( "#sfml-file-content" ).removeClass( "hide-if-js" ); } );</script>' . "\n";
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;
inc/url-filters.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ die( 'Cheatin\' uh?' );
4
+ }
5
+
6
+ /*------------------------------------------------------------------------------------------------*/
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 );
42
+ }
43
+
44
+ return $url;
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
+
74
+ if ( site_url( $base_uri ) === site_url( 'wp-login.php' ) ) {
75
+ return sfml_site_url( $location, $location, 'login', get_current_blog_id() );
76
+ }
77
+
78
+ return $location;
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 );
90
+ $login_url = wp_login_url();
91
+ restore_current_blog();
92
+
93
+ return str_replace( $url . 'wp-login.php', $login_url, $welcome_email );
94
+ }
inc/utilities.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
Binary file
languages/sf-move-login-fr_FR.po ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LANGUAGE French translation for Move Login plugin for WordPress.
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."
languages/sf-move-login-he_IL.mo ADDED
Binary file
languages/sf-move-login-he_IL.po ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file was generated by WPML
2
+ # WPML is a WordPress plugin that can turn any WordPress or WordPressMU site into a full featured multilingual content management system.
3
+ # http://wpml.org
4
+ msgid ""
5
+ msgstr ""
6
+ "Content-Type: text/plain; charset=UTF-8\n"
7
+ "Content-Transfer-Encoding: 8bit\n"
8
+ "Project-Id-Version: sf-move-login\n"
9
+ "POT-Creation-Date: \n"
10
+ "PO-Revision-Date: \n"
11
+ "Last-Translator: Ahrale <contact@atar4u.com>\n"
12
+ "Language-Team: Ahrale, Atar4U.com <contact@atar4u.com>\n"
13
+ "MIME-Version: 1.0\n"
14
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
+ "Language: he\n"
16
+ "X-Generator: Poedit 1.7.4\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+
19
+ # default:
20
+ # wp_die( __('No no no, the login form is not here.', 'sf-move-login') );
21
+ # }
22
+ # wpml-name: f02d96e29528d207eebb1134b60101a7
23
+ msgid "No no no, the login form is not here."
24
+ msgstr "לא לא לא, טופס ההתחברות אינו כאן."
25
+
26
+ # $error_msg = sprintf(
27
+ # __( 'An unexpected error occurred. Something may be wrong with screenfeed.fr or this server&#8217;s configuration. If you continue to have problems, please leave a message on <a href="%s">my blog</a>.', 'dad' ),
28
+ # 'http://www.screenfeed.fr/blog/'
29
+ # wpml-name: 1591a9d9cf0388df3f155337b9287402
30
+ msgid "An unexpected error occurred. Something may be wrong with screenfeed.fr or this server&#8217;s configuration. If you continue to have problems, please leave a message on <a href=\"%s\">my blog</a>."
31
+ msgstr "קרתה שגיאה לא צפויה. משהו השתבש ב screenfeed.fr או בתצורת השרת. אם הבעיה נמשכת, נא להשאיר הודעה ב <a href=\"%s\">אתר שלי</a>."
32
+
33
+ # 'upgrade' => __( 'To enable the real settings page for Move Login, please upgrade the plugin %2$s to the version %3$s (can also be %4$s).', 'sf-move-login' ),
34
+ # 'corrupted' => __( 'It seems the plugin Noop is installed but doesn\'t work properly. To enable the real settings page for Move Login, please reinstall %1$s (can also be %4$s).', 'sf-move-login' ),
35
+ # );
36
+ # wpml-name: 7baecfb459b11eeb9b6c66799c7620ae
37
+ msgid "It seems the plugin Noop is installed but doesn't work properly. To enable the real settings page for Move Login, please reinstall %1$s (can also be %4$s)."
38
+ msgstr "נראה שהתוסף Noop iמותקן אך אינו פועל כיאות. כדי להפעיל את ההגדרות האמתיות של Move Login,נא להתקין מחדש את %1$s (יכול להיות גם %4$s)."
39
+
40
+ # 'inactive' => __( 'To enable the real settings page for Move Login, please activate the plugin %2$s.', 'sf-move-login' ),
41
+ # 'upgrade' => __( 'To enable the real settings page for Move Login, please upgrade the plugin %2$s to the version %3$s (can also be %4$s).', 'sf-move-login' ),
42
+ # 'corrupted' => __( 'It seems the plugin Noop is installed but doesn\'t work properly. To enable the real settings page for Move Login, please reinstall %1$s (can also be %4$s).', 'sf-move-login' ),
43
+ # wpml-name: 36da2bdc510526c20591b7cfd057518e
44
+ msgid "To enable the real settings page for Move Login, please upgrade the plugin %2$s to the version %3$s (can also be %4$s)."
45
+ msgstr "כדי להפעיל את עמוד ההגדרות האמתיות של Move Login, נא לעדכן את התוסף %2$sלגרסה %3$s (יתכן גם %4$s)."
46
+
47
+ # 'required' => __( 'To enable the real settings page for Move Login, please install the plugin %1$s (can also be %4$s).', 'sf-move-login' ),
48
+ # 'inactive' => __( 'To enable the real settings page for Move Login, please activate the plugin %2$s.', 'sf-move-login' ),
49
+ # 'upgrade' => __( 'To enable the real settings page for Move Login, please upgrade the plugin %2$s to the version %3$s (can also be %4$s).', 'sf-move-login' ),
50
+ # wpml-name: e697e7e4931134ccb53a2b8dd3d2a69e
51
+ msgid "To enable the real settings page for Move Login, please activate the plugin %2$s."
52
+ msgstr "כדי להפעיל את ההגדרות האמתיות של התוסף, נא להפעיל את התוסף %2$s."
53
+
54
+ # 'updated_no_noop' => $status,
55
+ # 'updated_is_nginx' => sprintf( __('It seems your server uses a <i>Nginx</i> system, that I don\'t know at all. So I have to let you deal with the rewrite rules by yourself. Please visit the %2$s settings page and take a look at the rewrite rules used for a %1$s file. <strong>Move Login</strong> is running but won\'t work correctly until you deal with the rewrite rules.', 'sf-move-login'), $file, $link ),
56
+ # );
57
+ # wpml-name: c713e6cdc41d878d5fbd500cd38f1173
58
+ msgid "It seems your server uses a <i>Nginx</i> system, that I don't know at all. So I have to let you deal with the rewrite rules by yourself. Please visit the %2$s settings page and take a look at the rewrite rules used for a %1$s file. <strong>Move Login</strong> is running but won't work correctly until you deal with the rewrite rules."
59
+ msgstr "נראה שהשרת שלך משתמש במערכת <i>Nginx</i>, שאני כלל לא מכיר. כך שתצטרך להתעסק עם כללי הכתיבה מחדש בעצמך. נא לבקר בעמוד הגדרות %2$s settings pageותבדוק את כללי הכתיבה מחדש עבור קובץ %1$s. <strong>Move Login</strong> פועל כעת, אך לא יפעל נכון עד שתתקן את כללי הכתיבה מחדש."
60
+
61
+ # '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'),
62
+ # 'error_no_apache_nor_ii7' => __('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'),
63
+ # 'updated_no_noop' => $status,
64
+ # wpml-name: 71d17c00ac8e6e3bc6f49c3069c34c19
65
+ 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."
66
+ msgstr "נראה שהשרת שלך אינו משתמש ב <i>Apache</i>, <i>Nginx</i>, ולא ב <i>IIS7</i>. התוסף <strong>Move Login</strong> לא יפעל."
67
+
68
+ # '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'),
69
+ # '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'),
70
+ # 'error_no_apache_nor_ii7' => __('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'),
71
+ # wpml-name: 51ce773a89f2974a90312a44b147e0a9
72
+ msgid "It seems the url rewrite module is not activated on your server. <strong>Move Login</strong> won't work."
73
+ msgstr "נראה ש url rewrite module לא מופעל בשרת. התוסף <strong>Move Login</strong> לא יפעל."
74
+
75
+ # '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 ),
76
+ # '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'),
77
+ # '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'),
78
+ # wpml-name: 32917575d178bcce288c40d5fd2b8454
79
+ msgid "It seems your server configuration prevent the plugin to work properly. <strong>Move Login</strong> won't work."
80
+ msgstr "נראה שתצורת השרת שלך מונעת מן התוסף לפעול כראוי. התוסף <strong>Move Login</strong>לא יפעל."
81
+
82
+ # $messages = array(
83
+ # '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 ),
84
+ # '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'),
85
+ # wpml-name: 946acde8474d699b5fc41c462305d875
86
+ 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."
87
+ msgstr "התוסף <strong>Move Login</strong> צריך גישה לקובץ %1$s. נא לבקר בעמוד הגדרות %2$s והעתק והדבק את הקוד הזה אל קובץ ה %1$s."
88
+
89
+ # $dies = array_filter( array_map( 'sfml_notice_message', $dies ) );
90
+ # $die_msg = __('<strong>Move Login</strong> has not been activated.', 'sf-move-login').'<br/>';
91
+ # wp_die( $die_msg.implode('<br/>', $dies), __('Error'), array('back_link' => true) );
92
+ # wpml-name: b1029496bef7e7be27590701ceb5789b
93
+ msgid "<strong>Move Login</strong> has not been activated."
94
+ msgstr "התוסף <strong>Move Login</strong>לא הופעל."
95
+
96
+ # if ( $error )
97
+ # add_settings_error( 'sfml_settings', 'duplicates-slugs', __("The links can't have the same slugs.", 'sf-move-login') );
98
+ # }
99
+ # wpml-name: 59de4d4caf2239a3a5cbecb307f52544
100
+ msgid "The links can't have the same slugs."
101
+ msgstr "הקישורים לא יכולים להיות עם אותו סלאג."
102
+
103
+ # SFML_NOOP_VERSION,
104
+ # '<a href="' . sfml_noop_download_url() . '">' . __( 'downloaded separately', 'sf-move-login' ) . '</a>'
105
+ # );
106
+ # wpml-name: cd569714490eb4c3a5d3c64cddf5e79c
107
+ msgid "downloaded separately"
108
+ msgstr "הורד בנפרד"
109
+
110
+ # 'ok' => false,
111
+ # 'required' => __( 'To enable the real settings page for Move Login, please install the plugin %1$s (can also be %4$s).', 'sf-move-login' ),
112
+ # 'inactive' => __( 'To enable the real settings page for Move Login, please activate the plugin %2$s.', 'sf-move-login' ),
113
+ # wpml-name: 6c1678e35dc09ebe43f3a4b777753c24
114
+ msgid "To enable the real settings page for Move Login, please install the plugin %1$s (can also be %4$s)."
115
+ msgstr "כדי להפעיל את עמוד ההגדרות האמתיות להעברת החיבור, נא להתקין את התוסף %1$s (אפשר גם את %4$s)."
116
+
117
+ #
118
+ # $content = '<p>' . sprintf( __( 'If the plugin fails to add the new rewrite rules to your %1$s file on activation, 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' ), $file, '<code>'.$home_path.'</code>', 'SF Move Login', $above ) . "</p>\n";
119
+ # $content .= '<textarea class="code readonly auto-select" readonly="readonly" cols="120" rows="' . $height . '">' . esc_textarea( $htaccess_file ) . "</textarea>\n";
120
+ # wpml-name: adec20e3e5c732af573873eb2f7ad43f
121
+ msgid "If the plugin fails to add the new rewrite rules to your %1$s file on activation, 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:"
122
+ msgstr "אם התוסף נכשל בהוספת הכללים החדשים לקובץ %1$s בעת ההפעלה, הוסף ידנית לקובץ %1$s ב %2$s, להחלפת כללי %3$s אחרים אם הם קיימים, <strong>מעל</strong> לשורה שכתוב בה %4$s:"
123
+
124
+ # <div class='noop-form'>
125
+ # <h3><?php echo Noop_fields::section_icon('tools') . sprintf( __('%s File', 'sf-move-login'), $file ); ?></h3>
126
+ # <?php sfml_rewrite_rules_textarea(); ?>
127
+ # wpml-name: 0d9c8dfe174c5be68d35a4055031de0d
128
+ msgid "%s File"
129
+ msgstr "קובץ %s"
130
+
131
+ # 'next_under' => true,
132
+ # 'label' => '<strong>' . __('When a not connected user attempts to access the administration area.', 'sf-move-login') . '</strong>',
133
+ # )
134
+ # wpml-name: 7cb19ed3790a97a268761e9867e50227
135
+ msgid "When a not connected user attempts to access the administration area."
136
+ msgstr "כאשר משתמש שאינו מחובר מנסה לגשת ללוח הניהול."
137
+
138
+ # 'values' => array(
139
+ # 0 => __('Do nothing, redirect to the new login page', 'sf-move-login'),
140
+ # 1 => __('Display an error message', 'sf-move-login'),
141
+ # wpml-name: 10eb6282c69cde5f22353d887abb9d74
142
+ msgid "Do nothing, redirect to the new login page"
143
+ msgstr "אל תעשה כלום, מפנה מחדש לעמוד הכניסה החדש"
144
+
145
+ # 'deny_admin_access',
146
+ # __('Administration area', 'sf-move-login'),
147
+ # array( $fields, 'radio_field' ),
148
+ # wpml-name: 1bfa5d26f4aa776600904f0d8b979d4a
149
+ msgid "Administration area"
150
+ msgstr "לוח הניהול"
151
+
152
+ # 'next_under' => true,
153
+ # 'label' => '<strong>' . __('When a not connected user attempts to access the old login page.', 'sf-move-login') . '</strong>',
154
+ # )
155
+ # wpml-name: 9dcdd11578bd6149178058eb59b764dc
156
+ msgid "When a not connected user attempts to access the old login page."
157
+ msgstr "אשר משתמש שאינו מחובר מנסה לגשת לדף הכניסה הישן."
158
+
159
+ # 2 => __('Redirect to a &laquo;Page not found&raquo; error page', 'sf-move-login'),
160
+ # 3 => __('Redirect to the home page', 'sf-move-login'),
161
+ # ),
162
+ # wpml-name: 453b6eac755d93fede239ba7a2738c88
163
+ msgid "Redirect to the home page"
164
+ msgstr "הפנה מחדש אל דף הבית"
165
+
166
+ # 1 => __('Display an error message', 'sf-move-login'),
167
+ # 2 => __('Redirect to a &laquo;Page not found&raquo; error page', 'sf-move-login'),
168
+ # 3 => __('Redirect to the home page', 'sf-move-login'),
169
+ # wpml-name: 39681b2b1501410a64e80df46160bec3
170
+ msgid "Redirect to a &laquo;Page not found&raquo; error page"
171
+ msgstr "מפנה מחדש אל «העמוד לא נמצא» עמוד שגיאה"
172
+
173
+ # 0 => __('Do nothing, redirect to the new login page', 'sf-move-login'),
174
+ # 1 => __('Display an error message', 'sf-move-login'),
175
+ # 2 => __('Redirect to a &laquo;Page not found&raquo; error page', 'sf-move-login'),
176
+ # wpml-name: 19d2ee020263e6427da926706edce8d3
177
+ msgid "Display an error message"
178
+ msgstr "הצג הודעת שגיאה"
179
+
180
+ # if ( defined('SFML_ALLOW_LOGIN_ACCESS') && SFML_ALLOW_LOGIN_ACCESS ) {
181
+ # $description = '<span 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' ) . '</span>';
182
+ # Noop_fields::add_section_description( 'access', $description );
183
+ # wpml-name: 0b1058f191a430c5a9eca5a76381da3a
184
+ msgid "The constant <code>SFML_ALLOW_LOGIN_ACCESS</code> is defined to <code>true</code>, the settings below won't take effect."
185
+ msgstr "ה <code>SFML_ALLOW_LOGIN_ACCESS</code>הקבוע מוגדר ל <code>פועל</code>, ההגדרות שלהלן לא תשפענה."
186
+
187
+ # Noop_Settings::add_section( 'slugs', Noop_fields::section_icon('links') . __('Links') );
188
+ # Noop_Settings::add_section( 'access', Noop_fields::section_icon($is_new_admin ? 'admin-network' : 'site') . __('Access', 'sf-move-login') );
189
+ #
190
+ # wpml-name: bf733d8a933c1601697f364223fc7ecb
191
+ msgid "Access"
192
+ msgstr "גישה"
languages/sf-move-login-sr_RS.mo ADDED
Binary file
languages/sf-move-login-sr_RS.po ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LANGUAGE Serbo-Croatian translation for SF Move Login plugin for WordPress.
2
+ #
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: sf-move-login 1.1.4\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: 2014-12-15 22:19+0100\n"
9
+ "Last-Translator: Borisa Djuraskovic <borisad@webhostinghub.com>\n"
10
+ "Language-Team: sr_RS\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=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;_n\n"
17
+ "Language: sr_RS\n"
18
+ "X-Generator: Poedit 1.7.1\n"
19
+
20
+ # ---------------------------------------------------------------------------
21
+ # sf-move-login.php
22
+ msgid "Change your login url"
23
+ msgstr "Promenite svoj URL za prijavljivanje"
24
+
25
+ msgid "No no no, the login form is not here."
26
+ msgstr "Ne, ne, formular za prijavljivanje nije ovde."
27
+
28
+ # ---------------------------------------------------------------------------
29
+ # inc/noop.inc.php
30
+ msgid "The slug %s is forbidden."
31
+ msgid_plural "The slugs %s are forbidden."
32
+ msgstr[0] "Podloška %s je zabranjena."
33
+ msgstr[1] "Podloška %s je zabranjena."
34
+ msgstr[2] "Podloška %s je zabranjena."
35
+
36
+ msgid "The links can't have the same slugs."
37
+ msgstr "Linkovi ne mogu da imaju iste podloške."
38
+
39
+ # ---------------------------------------------------------------------------
40
+ # inc/admin.inc.php
41
+ msgid "Access"
42
+ msgstr "Pristup"
43
+
44
+ msgid "The constant <code>SFML_ALLOW_LOGIN_ACCESS</code> is defined to <code>true</code>, the settings below won't take effect."
45
+ msgstr "Konstanta <code>SFML_ALLOW_LOGIN_ACCESS</code> definisana je kao <code>istina</code>, podešavanja koja slede neće imati efekta."
46
+
47
+ msgid "Display an error message"
48
+ msgstr "Prikaži poruku da je došlo do greške"
49
+
50
+ msgid "Redirect to a &laquo;Page not found&raquo; error page"
51
+ msgstr "Preusmeri na &laquo;Stranica nije pronađena&raquo; stranica greške"
52
+
53
+ msgid "Redirect to the home page"
54
+ msgstr "Preusmeri na početnu stranicu"
55
+
56
+ msgid "When a not connected user attempts to access the old login page."
57
+ msgstr "Kad nepovezani korisnik pokuša da se prijavi na staru stranicu za prijavljivanje."
58
+
59
+ msgid "Administration area"
60
+ msgstr "Oblast administracije"
61
+
62
+ msgid "Do nothing, redirect to the new login page"
63
+ msgstr "Nemojte raditi ništa, preusmerite se na novu stranicu za prijavljivanje"
64
+
65
+ msgid "When a not connected user attempts to access the administration area."
66
+ msgstr "Kad nepovezani korisnik pokuša da pristupi administrativnoj oblasti."
67
+
68
+ msgid "%s File"
69
+ msgstr "%s datoteka"
70
+
71
+ msgid "If the plugin fails to add the new rewrite rules to your %1$s file on activation, 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:"
72
+ msgstr "Ako plugin ne uspe da doda nova pravila pisanja za vašu %1$s datoteku o aktivaciji, dodajte sledeće pravilo svojoj %1$s datoteci u %2$s zamenjujući druga %3$s pravila, ako postoje, <strong>iznad</strong>linije gde piše %4$s:"
73
+
74
+ # ---------------------------------------------------------------------------
75
+ # inc/plugins-list.inc.php
76
+ msgid "<strong>Move Login</strong> has not been activated."
77
+ msgstr "<strong>Premesti prijavljivanje</strong>nije aktivirano."
78
+
79
+ 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."
80
+ msgstr "<strong>Premesti prijavljivanje</strong>zahteva pristup %1$s datoteci. Posetite %2$s stranicu podešavanja, kopirajte i nalepite dati kod u %1$s datoteku."
81
+
82
+ msgid "It seems your server configuration prevent the plugin to work properly. <strong>Move Login</strong> won't work."
83
+ msgstr "Izgleda da konfiguracija vašeg servera sprečava plugin da radi kako treba. <strong>Premesti prijavljivanje</strong> neće da radi."
84
+
85
+ msgid "It seems the url rewrite module is not activated on your server. <strong>Move Login</strong> won't work."
86
+ msgstr "Izgleda da modul za ponovno ispisivanje url-a nije aktiviran na vašem serveru. <strong>Premesti prijavljivanje</strong> neće da radi."
87
+
88
+ 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."
89
+ msgstr "Izgleda da vaš server ne koristi <i>Apache</i>, <i>Nginx</i> niti <i>IIS7</i>. <strong>Premesti prijavljivanje</strong> neće da radi."
90
+
91
+ msgid "It seems your server uses a <i>Nginx</i> system, that I don't know at all. So I have to let you deal with the rewrite rules by yourself. Please visit the %2$s settings page and take a look at the rewrite rules used for a %1$s file. <strong>Move Login</strong> is running but won't work correctly until you deal with the rewrite rules."
92
+ msgstr "Izgleda da vaš server koristi <i>Nginx</i> koji uopšte ne poznajem. Moram vas pustiti da se sami izborite sa pravilima ponovnog pisanja. Posetite %2$s stranicu podešavanja i pogledajte pravila ponovnog pisanja koja se koriste za %1$s datoteku. <strong>Premesti prijavljivanje</strong> je pokrenuto, ali neće da radi kako treba dok ne rešite pravila za ponovno pisanje."
93
+
94
+ msgid "To enable the real settings page for Move Login, please install the plugin %1$s."
95
+ msgstr "Da biste aktivirali pravu stranicu podešavanja za ‘Premesti prijavljivanje’, instalirajte plugin %1$s."
96
+
97
+ msgid "To enable the real settings page for Move Login, please activate the plugin %2$s."
98
+ msgstr "Da biste aktivirali pravu stranicu podešavanja za ‘Premesti prijavljivanje’, aktivirajte plugin %2$s."
99
+
100
+ msgid "To enable the real settings page for Move Login, please upgrade the plugin %2$s to the version %3$s."
101
+ msgstr "Da biste aktivirali pravu stranicu podešavanja za ‘Premesti prijavljivanje’, nadogradite plugin %2$s na verziju %3$s."
102
+
103
+ msgid "It seems the plugin Noop is installed but doesn't work properly. To enable the real settings page for Move Login, please reinstall %1$s."
104
+ msgstr "Izgleda da je plugin Noop instaliran, ali ne radi kako treba. Da biste aktivirali pravu stranicu podešavanja za ‘Premesti prijavljivanje’, ponovo instalirajte %1$s."
languages/sfml-fr_FR.mo DELETED
Binary file
languages/sfml-fr_FR.po DELETED
@@ -1,38 +0,0 @@
1
- # LANGUAGE French translation for SF Move Login plugin for WordPress.
2
- # Copyright (C) 2013 Grégory Viguier
3
- # Grégory Viguier.
4
- #
5
- msgid ""
6
- msgstr ""
7
- "Project-Id-Version: w3p-acpt 0.3\n"
8
- "Report-msgid -Bugs-To: http://scri.in/contact/\n"
9
- "POT-Creation-Date: 2013-06-01 00:04+0100\n"
10
- "PO-Revision-Date: 2013-06-03 01:57+0100\n"
11
- "Last-Translator: Grégory Viguier <gregory@screenfeed.fr>\n"
12
- "Language-Team: fr_FR\n"
13
- "MIME-Version: 1.0\n"
14
- "Content-Type: text/plain; charset=utf-8\n"
15
- "Content-Transfer-Encoding: 8bit\n"
16
- "Plural-Forms: nplurals=2; plural=n>1;\n"
17
- "X-Poedit-SourceCharset: utf-8\n"
18
- "X-Poedit-KeywordsList: __;_e\n"
19
- "Language: fr_FR\n"
20
- "X-Generator: Poedit 1.5.5\n"
21
-
22
- msgid "Change your login url to http://example.com/login"
23
- msgstr "Changez l'url de votre page de connexion pour http://example.com/login"
24
-
25
- msgid "Please Make sure to enable %s."
26
- msgstr "Assurez-vous d'activer les %s."
27
-
28
- msgid "It seems your server configuration prevent the plugin to work properly. <i>SF Move Login</i> will not be activated."
29
- msgstr "Il semble que votre configuration serveur empêche l'extension de fonctionner correctement. <i>SF Move Login</i> ne sera pas activé."
30
-
31
- msgid "<strong>SF Move Login</strong> has not been activated."
32
- msgstr "<strong>SF Move Login</strong> n'a pas été activé."
33
-
34
- msgid "<i>SF Move Login</i> 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."
35
- msgstr "<i>SF Move Login</i> a besoin d'accéder au fichier %1$s. Merci de vous rendre sur la page de réglages des %2$s et de copier/coller le code fourni dans le fichier %1$s."
36
-
37
- msgid "No no no, the login form is not here."
38
- msgstr "Non non non, le formulaire de connexion ne se trouve pas ici."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,68 +1,235 @@
1
- === SF Move Login ===
2
 
3
- Contributors: GregLone, juliobox
4
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=UBY2MY2J4YB7J&item_number=SF-Move-Login
5
  Tags: login, logout, url, security
6
- Requires at least: 3.0
7
- Tested up to: 3.6-beta3
8
  Stable tag: trunk
9
  License: GPLv3
 
10
 
11
- Change your login url to http://example.com/login.
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
 
18
- This is a great way to limit bots trying to brute-forcing your login (trying to guess your login and password). Of course, the new urls are easier to remember too.
19
- The plugin is small, fast, and does not create new security vulnerabilities like some other plugins I've seen.
20
-
21
- No settings: activate, it works.
22
-
23
- Also remember: using this plugin does NOT exempt you to use a strong password. Moreover, never use "admin" as login, this is the first attempt for bots.
24
-
25
- **Please note that the plugin works properly so far, but still in beta.**
26
 
27
  = Translations =
28
 
29
- * English
30
  * French
 
 
31
 
32
  = Multisite =
33
 
34
- Not tested, but should be ready for Multisite.
 
 
 
35
 
36
  = Requirements =
37
 
38
- See some important informations in the "Installation" tab.
 
 
39
 
40
 
41
  == Installation ==
42
 
43
  1. Extract the plugin folder from the downloaded ZIP file.
44
- 2. Upload sf-move-login folder to your `/wp-content/plugins/` directory.
45
- 3. Enable url rewriting in the permalinks settings page.
46
- 4. if you have another plugin that redirects **http://example.com/login** 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
- 5. Activate the plugin from the "Plugins" page.
48
- 6. If the plugin can't write your `.htaccess` file, you'll need to edit it yourself with a ftp access.
49
 
50
 
51
  == Frequently Asked Questions ==
52
 
53
- = Can I set my own urls? =
54
 
55
- Nop, sorry. I prefer keep the plugin as simple as possible.
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
- Eventually, check out [my blog](http://www.screenfeed.fr/sfml/) for more infos, help, or bug reports (sorry guys, it's in french, but feel free to leave a comment in english).
 
 
62
 
63
 
64
  == Changelog ==
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  = 0.1 =
67
 
68
  * 2013/06/03
@@ -72,4 +239,11 @@ Eventually, check out [my blog](http://www.screenfeed.fr/sfml/) for more infos,
72
 
73
  == Upgrade Notice ==
74
 
75
- Nothing special
 
 
 
 
 
 
 
1
+ === Move Login ===
2
 
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
24
  * French
25
+ * Serbo-Croatian (partial, thank you Borisa)
26
+ * Hebrew (partial, thank you Ahrale)
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
 
41
 
42
  == Installation ==
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 ==
52
 
53
+ = Can I set my own URLs? =
54
 
55
+ Since the version 1.1, yes. And since the version 2.0, you don't need any additional plugin for that.
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 ==
69
+
70
+ 1. The settings page.
71
 
72
 
73
  == Changelog ==
74
 
75
+ = 2.3 =
76
+
77
+ * 2016/04/04
78
+ * Tested with WP 4.5.
79
+ * Code quality improvements.
80
+ * Fixed [a notice with php7](https://wordpress.org/support/topic/php7-php-notice-only-variables-should-be-passed-by-reference).
81
+ * Mark the option "Do nothing, redirect to the new login page" as [not recommended](https://wordpress.org/support/topic/do-nothing-redirect-to-the-new-login-page-gives-away-the-hidden-url).
82
+ * If not logged in, deny access to `wp-signup.php` and `wp-register.php` (mono-site installations).
83
+ * When blocking access, use a 501 error code instead of 500.
84
+ * Added compatibility with websites that are not using port 80 and 443.
85
+
86
+ = 2.2.2 =
87
+
88
+ * 2015/11/22
89
+ * Login over https on a non https site should finally work (๑˃̵ᴗ˂̵)و
90
+
91
+ = 2.2.1 =
92
+
93
+ * 2015/10/04
94
+ * The URL used in the password protected posts form (slug `postpass`) is back in the rewrite rules: this URL can be discovered by inspecting the form code, so it must not use the login URL.
95
+ * Bugfix: the URL used in the password protected posts form and those used to retrieve a password are working fine again.
96
+
97
+ = 2.2 =
98
+
99
+ * 2015/09/18
100
+ * Removed `postpass`, `retrievepassword` and `rp` from the rewrite rules: they are useless and they can be used to find the login page.
101
+ * Fixed a bug in multisite where rewrite rules were inserted after the WordPress rules.
102
+ * The plugin will not display a message ON EVERY BLOODY UPDATE anymore, only if the `.htaccess`/`web.config` file needs to be updated and it is not writeable. Well, too bad... it is the case this time. (╯°□°)╯︵ ┻━┻
103
+ * The code box after the settings form is now hidden by default and can be shown by clicking a button.
104
+ * Some code cleanup.
105
+
106
+ = 2.1.5 =
107
+
108
+ * 2015/08/26
109
+ * Back-compat is getting annoying. Last try before dropping support of old versions of WP.
110
+
111
+ = 2.1.4 =
112
+
113
+ * 2015/08/26
114
+ * Bugfix for WP < 3.6: `Call to undefined function wp_is_writable()`.
115
+
116
+ = 2.1.3 =
117
+
118
+ * 2015/08/05
119
+ * New: ready for the new WordPress 4.3 headings in admin screens (but you won't see any difference).
120
+
121
+ = 2.1.2 =
122
+
123
+ * 2015/07/23
124
+ * Bugfix: Added missing base URL in rewrite rules for Nginx when the site is not installed at the domain root.
125
+ * Bugfix: php warning in settings page.
126
+
127
+ = 2.1.1 =
128
+
129
+ * 2015/06/08
130
+ * Bugfix: Added missing semicolon in rewrite rules for Nginx.
131
+
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()`.
139
+ * Bugfix: slugs were not stored in `SFML_Options::get_slugs()` before being returned. Trivial perf improvement.
140
+ * The filter 'sfml_options' can't be used to add options, only to modify existing values.
141
+ * Removed some unused global vars.
142
+
143
+ = 2.0.2 =
144
+
145
+ * 2015/02/24
146
+ * Same as below... Fingers crossed. >_>
147
+
148
+ = 2.0.1 =
149
+
150
+ * 2015/02/24
151
+ * Fixes a fatal error for multisites.
152
+
153
+ = 2.0 =
154
+
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.
162
+ * Bugfix: fix double slash in network site url (used for lostpassword).
163
+
164
+ = 1.1.4 =
165
+
166
+ * 2014/04/28
167
+ * Plugins can now add their own action to Move Login more easily with the filter `sfml_additional_slugs`. Even without doing anything, Move Login handle custom actions added by other plugins, but the url can't be customizable. Now, these plugins can add a new input field to let users change this new url, and it's very simple.
168
+ * Side note: I've just released a new version for my framework Noop (1.0.6). Now you can import and export your settings via a file, see the new tab in the "Help" area.
169
+
170
+ = 1.1.3 =
171
+
172
+ * 2014/04/01
173
+ * Bugfix for php 5.4.
174
+
175
+ = 1.1.2 =
176
+
177
+ * 2014/03/29
178
+ * Bugfix: don't block users accessing the script `admin-post.php`.
179
+ * Changed i18n domain.
180
+ * If Noop is not installed, add a link in the "settings" page.
181
+ * Added a direct link to download Noop, some users may not be able to install plugins directly.
182
+ * Code improvements and small bugfixes.
183
+
184
+ = 1.1.1 =
185
+
186
+ * 2013/12/17
187
+ * Bugfix.
188
+
189
+ = 1.1 =
190
+
191
+ * 2013/12/16
192
+ * Code refactoring.
193
+ * Requires WordPress 3.1 at least.
194
+ * New: the URLs can be customized, with a filter or a settings page. The settings page needs another plugin to be installed, it's a framework I made (Noop). See the Move Login row in your plugins list, there's a new link.
195
+ * New: support for custom actions in the login form (added by other plugins).
196
+ * New: choose what to do when someone attempts to access the old login page.
197
+ * New: choose what to do when someone attempts to access the administration area.
198
+ * New: enabling permalinks is not required anymore.
199
+ * Todo: provide rewrite rules for Nginx systems.
200
+
201
+ = 1.0.1 =
202
+
203
+ * 2013/09/30
204
+ * Very minor bug fix: messed the author link -_-'
205
+
206
+ = 1.0 =
207
+
208
+ * 2013/09/20
209
+ * First stable version.
210
+ * New: 1 new action called `sfml_wp_login_error` is now available for the `wp-login.php` error message, you can use your own `wp_die()` or redirect to another error page for example.
211
+
212
+ = 1.0-RC2 =
213
+
214
+ * 2013/09/12
215
+ * Bugfix: activation for multisite with not writable .htaccess file, a wrong message was shown, preventing activation (was I drunk?).
216
+ * tested on multisite with subdomain.
217
+ * SecuPress is joining the project :)
218
+
219
+ = 1.0-RC1 =
220
+
221
+ * 2013/09/11
222
+ * New: Multisite support (must be "network" activated).
223
+ * Enhancement: updated the set_url_scheme() function to the one in WP 3.6.1 (used for WP < 3.4).
224
+ * Enhancement: better rewrite rules.
225
+ * Bugfix: The plugin rewrite rules are now really removed from the .htaccess file on deactivation.
226
+
227
+ = 0.1.1 =
228
+
229
+ * 2013/06/04
230
+ * Bugfix: php notice due to a missing parameter.
231
+ * Bugfix: incorrect network_site_url filter.
232
+
233
  = 0.1 =
234
 
235
  * 2013/06/03
239
 
240
  == Upgrade Notice ==
241
 
242
+ = 2.1 =
243
+ Support for installations where WordPress has its own directory.
244
+
245
+ = 2.0 =
246
+ The framework Noop is not needed anymore: settings are included in the plugin. Make sure your settings are ok after upgrading.
247
+
248
+ = 1.0 =
249
+ This is the first stable version of the plugin.
sf-move-login.php CHANGED
@@ -1,251 +1,78 @@
1
  <?php
2
  /*
3
  * Plugin Name: SF Move Login
4
- * Plugin URI: http://www.screenfeed.fr
5
- * Description: Change your login url to http://example.com/login
6
- * Version: 0.1
7
  * Author: Grégory Viguier
8
- * Author URI: http:www.screenfeed.fr/greg/
9
  * License: GPLv3
10
- * Require: WordPress 3.0
11
- * Text Domain: sfml
 
12
  * Domain Path: /languages/
13
  */
14
 
15
- /* ----------------------------------------------------------------------------- */
16
- /* */
17
- /* Activation / Deactivation */
18
- /* */
19
- /* ----------------------------------------------------------------------------- */
20
-
21
- register_activation_hook( __FILE__, 'sfml_activate' );
22
- function sfml_activate() {
23
- $dies = array();
24
- $notices = array();
25
- $home_path = get_home_path();
26
- load_plugin_textdomain( 'sfml', false, basename( dirname( __FILE__ ) ) . '/languages/' ); // wp_die() will need i18n
27
-
28
- if ( iis7_supports_permalinks() ) {
29
- if ( !( ( !file_exists($home_path . 'web.config') && win_is_writable($home_path) ) || win_is_writable($home_path . 'web.config') ) )
30
- $notices[] = 'htaccess_not_writable';
31
- } else {
32
- if ( !( ( !file_exists($home_path . '.htaccess') && is_writable($home_path) ) || is_writable($home_path . '.htaccess') ) )
33
- $notices[] = 'htaccess_not_writable';
34
- }
35
- if ( !get_option('permalink_structure') )
36
- $dies[] = sprintf(__('Please Make sure to enable %s.', 'sfml'), '<a href="options-permalink.php">'.__('Permalinks').'</a>');
37
-
38
- if ( empty($GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI']) && empty($_SERVER['REQUEST_URI']) )
39
- $dies[] = __('It seems your server configuration prevent the plugin to work properly. <i>SF Move Login</i> will not be activated.', 'sfml');
40
-
41
- if ( count($dies) ) {
42
- wp_die( __('<strong>SF Move Login</strong> has not been activated.', 'sfml').'<br/>'.implode('<br/>', $dies), __('Error'), array('back_link' => true) );
43
- } else {
44
- if ( count($notices) )
45
- set_transient('sfml_notices-'.get_current_user_id(), $notices);
46
- sfml_rewrite();
47
- flush_rewrite_rules();
48
- }
49
  }
50
 
51
-
52
- register_deactivation_hook( __FILE__, 'flush_rewrite_rules' );
53
-
54
-
55
- // !Admin notices
56
-
57
- add_action('admin_init', 'sfml_notices');
58
- function sfml_notices() {
59
- $user_id = get_current_user_id();
60
- $notices = get_transient('sfml_notices-'.$user_id);
61
-
62
- if ( $notices && is_array($notices) && count($notices) ) {
63
- foreach ( $notices as $notice ) {
64
- add_action('admin_notices', 'sfml_'.$notice.'_notice');
65
- }
66
- delete_transient('sfml_notices-'.$user_id);
67
- }
68
  }
69
 
 
 
 
70
 
71
- function sfml_htaccess_not_writable_notice() {
72
- $file = iis7_supports_permalinks() ? '<code>web.config</code>' : '<code>.htaccess</code>';
73
- echo '<div class="error"><p>'
74
- .sprintf(
75
- __('<i>SF Move Login</i> 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.', 'sfml'),
76
- $file,
77
- '<a href="options-permalink.php">'.__('Permalinks').'</a>'
78
- )
79
- .'</p></div>';
80
- }
81
-
82
 
83
- /* ----------------------------------------------------------------------------- */
84
- /* */
85
- /* i18n support */
86
- /* */
87
- /* ----------------------------------------------------------------------------- */
88
 
89
- add_action( 'init', 'sfml_lang_init' );
90
- function sfml_lang_init() {
91
- load_plugin_textdomain( 'sfml', false, basename( dirname( __FILE__ ) ) . '/languages/' );
92
- }
93
 
 
94
 
95
- /* ----------------------------------------------------------------------------- */
96
- /* */
97
- /* Rewrite rules */
98
- /* */
99
- /* ----------------------------------------------------------------------------- */
100
 
101
- add_action( 'setup_theme', 'sfml_rewrite' );
102
- function sfml_rewrite() {
103
- add_rewrite_rule( 'login/?([\?&].*)?$', 'wp-login.php', 'top' );
104
- $actions = array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register' );
105
- foreach ( $actions as $action ) {
106
- add_rewrite_rule( $action.'/?([\?&].*)?$', 'wp-login.php?action='.$action, 'top' );
107
  }
108
- }
109
-
110
-
111
- /* ----------------------------------------------------------------------------- */
112
- /* */
113
- /* Bypass */
114
- /* */
115
- /* ----------------------------------------------------------------------------- */
116
-
117
- if ( defined('SFML_ALLOW_LOGIN_ACCESS') && SFML_ALLOW_LOGIN_ACCESS )
118
- return;
119
-
120
 
121
- /* ----------------------------------------------------------------------------- */
122
- /* */
123
- /* Filter urls */
124
- /* */
125
- /* ----------------------------------------------------------------------------- */
126
-
127
- // !Site URL
128
- add_filter( 'site_url', 'sfml_site_url', 10, 4);
129
- function sfml_site_url( $url, $path, $scheme, $blog_id ) {
130
- if ( ($scheme === 'login' || $scheme === 'login_post') && !empty($path) && is_string($path) && strpos($path, '..') === false && strpos($path, 'wp-login.php') !== false ) {
131
- // Base url
132
- if ( empty( $blog_id ) || !is_multisite() ) {
133
- $url = get_option( 'siteurl' );
134
- } else {
135
- switch_to_blog( $blog_id );
136
- $url = get_option( 'siteurl' );
137
- restore_current_blog();
138
- }
139
- $url = set_url_scheme( $url, $scheme );
140
-
141
- // Action
142
- $parsed_path = parse_url( $path );
143
- if ( !empty( $parsed_path['query'] ) ) {
144
- wp_parse_str( $parsed_path['query'], $params );
145
- $action = !empty( $params['action'] ) ? $params['action'] : 'login';
146
-
147
- if ( isset( $params['key'] ) )
148
- $action = 'resetpass';
149
-
150
- if ( !in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) && false === has_filter( 'login_form_' . $action ) )
151
- $action = 'login';
152
- } else
153
- $action = 'login';
154
-
155
- // Path
156
- $path = str_replace('wp-login.php', $action, $path);
157
- $path = remove_query_arg('action', $path);
158
-
159
- return $url . '/' . ltrim( $path, '/' );
160
  }
161
- return $url;
162
- }
163
-
164
-
165
- // !Network site URL
166
- add_filter( 'network_site_url', 'sfml_site_url', 10, 3);
167
-
168
- // !Utility: /login?action=logout -> /logout
169
- function sfml_login_to_action( $link, $action ) {
170
- if ( $link && strpos($link, '/'.$action) === false )
171
- return str_replace(array('/login', '&amp;', '?amp;', '&'), array('/'.$action, '&', '?', '&amp;'), remove_query_arg('action', $link));
172
- return $link;
173
- }
174
 
175
-
176
- // !Logout url: wp_logout_url() add the action param after using site_url()
177
- add_filter( 'logout_url', 'sfml_logout_url' );
178
- function sfml_logout_url( $link ) {
179
- return sfml_login_to_action( $link, 'logout' );
180
- }
181
-
182
-
183
- // !Forgot password url: lostpassword_url() add the action param after using site_url()
184
- add_filter( 'lostpassword_url', 'sfml_lostpass_url' );
185
- function sfml_lostpass_url( $link ) {
186
- return sfml_login_to_action( $link, 'lostpassword' );
187
- }
188
-
189
-
190
- /* ----------------------------------------------------------------------------- */
191
- /* */
192
- /* Redirections */
193
- /* */
194
- /* ----------------------------------------------------------------------------- */
195
-
196
- // !Redirections are hard-coded
197
- add_filter('wp_redirect', 'sfml_redirect', 10, 2);
198
- function sfml_redirect( $location, $status ) {
199
- if ( site_url( reset( explode( '?', $location ) ) ) == site_url( 'wp-login.php' ) )
200
- return sfml_site_url( $location, $location, 'login' );
201
-
202
- return $location;
203
  }
204
 
205
 
206
- /* ----------------------------------------------------------------------------- */
207
- /* */
208
- /* Block access to wp-login.php */
209
- /* */
210
- /* ----------------------------------------------------------------------------- */
211
 
212
- // !No, you won't use wp-login.php
213
- add_action( 'login_init', 'sfml_login_init', 0 );
214
- function sfml_login_init() {
215
- $uri = !empty($GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI']) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : (!empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '');
216
- $uri = parse_url( $uri );
217
- $uri = !empty($uri['path']) ? str_replace( '/', '', basename($uri['path']) ) : '';
218
 
219
- if ( $uri === 'wp-login.php' )
220
- wp_die(__('No no no, the login form is not here.', 'sfml'));
221
  }
222
 
223
 
224
- /* ----------------------------------------------------------------------------- */
225
- /* */
226
- /* For WP < 3.4 */
227
- /* */
228
- /* ----------------------------------------------------------------------------- */
229
-
230
- if ( !function_exists('set_url_scheme') ):
231
- function set_url_scheme( $url, $scheme = null ) {
232
- $orig_scheme = $scheme;
233
- if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
234
- if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) )
235
- $scheme = 'https';
236
- elseif ( ( 'login' == $scheme ) && force_ssl_admin() )
237
- $scheme = 'https';
238
- elseif ( ( 'admin' == $scheme ) && force_ssl_admin() )
239
- $scheme = 'https';
240
- else
241
- $scheme = ( is_ssl() ? 'https' : 'http' );
242
- }
243
-
244
- if ( 'relative' == $scheme )
245
- $url = preg_replace( '#^.+://[^/]*#', '', $url );
246
- else
247
- $url = preg_replace( '#^.+://#', $scheme . '://', $url );
248
 
249
- return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );
 
250
  }
251
- endif;
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
10
+ * License URI: https://www.screenfeed.fr/gpl-v3.txt
11
+ * Network: true
12
+ * Text Domain: sf-move-login
13
  * Domain Path: /languages/
14
  */
15
 
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ die( 'Cheatin\' uh?' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
+ if ( version_compare( $GLOBALS['wp_version'], '3.1', '<' ) ) {
21
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
+ /*------------------------------------------------------------------------------------------------*/
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 ) );
 
 
 
 
 
 
 
32
 
 
 
 
 
 
33
 
34
+ /*------------------------------------------------------------------------------------------------*/
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
 
61
+ /*------------------------------------------------------------------------------------------------*/
62
+ /* !I18N SUPPORT ================================================================================ */
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
  }
 
uninstall.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
3
+ die();
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 );