Erident Custom Login and Dashboard - Version 4.1

Version Description

| July 19, 2022 = * Announcement: Erident Custom Login & Dashboard is now Ultimate Dashboard! You will be greeted with a 1-click migration to safely migrate from Erident to Ultimate Dashboard. Learn more about why we have made this decision in the announcement post - https://ultimatedashboard.io/blog/erident-custom-login-dashboard-is-now-ultimate-dashboard/ * Fixed: Form background image button didn't trigger the media popup

Download this release

Release Info

Developer davidvongries
Plugin Icon 128x128 Erident Custom Login and Dashboard
Version 4.1
Comparing to
See all releases

Code changes from version 4.0.1 to 4.1

ajax/class-migration.php ADDED
@@ -0,0 +1,525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Change widget order.
4
+ *
5
+ * @package Swift_Control
6
+ */
7
+
8
+ namespace CustomLoginDashboard\Ajax;
9
+
10
+ /**
11
+ * Class to manage ajax request of migration to UDB.
12
+ */
13
+ class Migration {
14
+
15
+ /**
16
+ * The old plugin slug.
17
+ *
18
+ * @var string
19
+ */
20
+ private $old_plugin_basename = '';
21
+
22
+ /**
23
+ * Class constructor.
24
+ */
25
+ public function __construct() {
26
+
27
+ add_action( 'wp_ajax_cldashboard_migration', [ $this, 'handler' ] );
28
+
29
+ }
30
+
31
+ /**
32
+ * The request handler.
33
+ */
34
+ public function handler() {
35
+
36
+ $this->validate();
37
+ $this->migrate();
38
+
39
+ }
40
+
41
+ /**
42
+ * Validate the data.
43
+ */
44
+ private function validate() {
45
+
46
+ // Check if nonce is incorrect.
47
+ if ( ! check_ajax_referer( 'cldashboard_nonce_migration', 'nonce', false ) ) {
48
+ wp_send_json_error( __( 'Invalid token', 'erident-custom-login-and-dashboard' ), 401 );
49
+ }
50
+
51
+ // Check against old plugin basename existence.
52
+ if ( ! isset( $_POST['old_plugin_basename'] ) || empty( $_POST['old_plugin_basename'] ) ) {
53
+ wp_send_json_error( __( 'Old plugin basename is not specified', 'erident-custom-login-and-dashboard' ), 401 );
54
+ }
55
+
56
+ if (
57
+ defined( 'ULTIMATE_DASHBOARD_PLUGIN_VERSION' )
58
+ || file_exists( WP_CONTENT_DIR . '/plugins/ultimate-dashboard/ultimate-dashboard.php' )
59
+ ) {
60
+ wp_send_json_error(
61
+ __(
62
+ 'You already have Ultimate Dashboard installed. You may want to uninstall Ultimate Dashboard manually and start the migration again. Make sure the "Remove Data on Uninstall" option in Ultimate Dashboard is NOT checked so that your existing Ultimate Dashboard settings will stay in place.',
63
+ 'erident-custom-login-and-dashboard'
64
+ ),
65
+ 401
66
+ );
67
+ }
68
+
69
+ if ( ! function_exists( 'fsockopen' ) ) {
70
+ wp_send_json_error(
71
+ __(
72
+ 'Your server does not have the fsockopen function enabled. This is required to check the internet connection. Please contact your host and ask them to enable this function.',
73
+ 'erident-custom-login-and-dashboard'
74
+ ),
75
+ 503
76
+ );
77
+ }
78
+
79
+ $internet_connected = $this->is_internet_connected();
80
+ $internet_connected = ! $internet_connected ? $this->is_internet_connected( 443 ) : $internet_connected;
81
+
82
+ // Check against internet connection.
83
+ if ( ! $internet_connected ) {
84
+ wp_send_json_error( 'Seems like you are not connected to the internet. A stable connection is required to download the Ultimate Dashboard plugin.<br>Please check your internet connection. If you are using a proxy, try to disable it.', 503 );
85
+ }
86
+
87
+ $this->old_plugin_basename = sanitize_text_field( $_POST['old_plugin_basename'] );
88
+ }
89
+
90
+ /**
91
+ * Check if the internet is connected.
92
+ *
93
+ * Thanks to Alfred <https://stackoverflow.com/users/484082/alfred>
94
+ *
95
+ * @link https://stackoverflow.com/questions/4860365/determine-in-php-script-if-connected-to-internet#answer-4860432
96
+ *
97
+ * @param int $port The port to check.
98
+ * @return bool
99
+ */
100
+ private function is_internet_connected( $port = 80 ) {
101
+
102
+ // Website, port (try 80 or 443).
103
+ $connected = @fsockopen( 'google.com', 80 );
104
+
105
+ if ( $connected ) {
106
+ // Action when connected.
107
+ $is_connected = true;
108
+ fclose( $connected );
109
+ } else {
110
+ // Action in connection failure.
111
+ $is_connected = false;
112
+ }
113
+
114
+ return $is_connected;
115
+
116
+ }
117
+
118
+ /**
119
+ * Migrate to Ultimate Dashboard.
120
+ */
121
+ private function migrate() {
122
+
123
+ if ( ! file_exists( WP_PLUGIN_DIR . '/' . $this->old_plugin_basename ) ) {
124
+ wp_send_json_error( __( 'Erident Custom Login & Dashboard plugin is not found', 'erident-custom-login-and-dashboard' ), 403 );
125
+ }
126
+
127
+ $this->migrate_settings();
128
+
129
+ update_option( 'udb_migration_from_erident', 1 );
130
+
131
+ deactivate_plugins( $this->old_plugin_basename );
132
+
133
+ $deletion = delete_plugins( [ $this->old_plugin_basename ] );
134
+
135
+ if ( $deletion && ! is_wp_error( $deletion ) ) {
136
+ // If the plugin is deleted successfully, let's delete the option.
137
+ delete_option( 'plugin_erident_settings' );
138
+ wp_send_json_success( __( 'Erident Custom Login & Dashboard plugin has been removed', 'erident-custom-login-and-dashboard' ) );
139
+ } elseif ( is_wp_error( $deletion ) ) {
140
+ wp_send_json_error( $deletion->get_error_message(), 403 );
141
+ } elseif ( null === $deletion ) {
142
+ wp_send_json_error( __( 'Filesystem credentials are required', 'erident-custom-login-and-dashboard' ), 403 );
143
+ } else {
144
+ wp_send_json_error( __( 'Erident Custom Login & Dashboard plugin is not specified', 'erident-custom-login-and-dashboard' ), 401 );
145
+ }
146
+
147
+ }
148
+
149
+ /**
150
+ * Migrate Erident Custom Login & Dashboard settings to Ultimate Dashboard settings.
151
+ */
152
+ private function migrate_settings() {
153
+
154
+ $this->migrate_general_settings();
155
+ $this->migrate_login_settings();
156
+
157
+ }
158
+
159
+ /**
160
+ * Migrate general settings.
161
+ */
162
+ private function migrate_general_settings() {
163
+
164
+ $udb_general_options = get_option( 'udb_settings', [] );
165
+ $udb_branding_options = get_option( 'udb_branding', [] );
166
+ $erident_options = get_option( 'plugin_erident_settings', [] );
167
+
168
+ if ( empty( $erident_options ) ) {
169
+ return;
170
+ }
171
+
172
+ $is_general_changed = false;
173
+ $is_branding_changed = false;
174
+
175
+ $clean_deactivation = isset( $erident_options['dashboard_delete_db'] ) ? $erident_options['dashboard_delete_db'] : 0;
176
+ $clean_deactivation = 'yes' === strtolower( $clean_deactivation ) ? 1 : $clean_deactivation;
177
+ $clean_deactivation = 'no' === strtolower( $clean_deactivation ) ? 0 : $clean_deactivation;
178
+
179
+ if ( $clean_deactivation ) {
180
+ $udb_general_options['remove-on-uninstall'] = 1;
181
+
182
+ $is_general_changed = true;
183
+ }
184
+
185
+ $footer_text = isset( $erident_options['dashboard_data_left'] ) ? stripslashes( $erident_options['dashboard_data_left'] ) : '';
186
+
187
+ if ( $footer_text ) {
188
+ $udb_branding_options['footer_text'] = $footer_text;
189
+
190
+ $is_branding_changed = true;
191
+ }
192
+
193
+ $version_text = isset( $erident_options['dashboard_data_right'] ) ? stripslashes( $erident_options['dashboard_data_right'] ) : '';
194
+
195
+ if ( $version_text ) {
196
+ $udb_branding_options['version_text'] = $version_text;
197
+
198
+ $is_branding_changed = true;
199
+ }
200
+
201
+ if ( $is_general_changed ) {
202
+ update_option( 'udb_settings', $udb_general_options );
203
+ }
204
+
205
+ if ( $is_branding_changed ) {
206
+ update_option( 'udb_branding', $udb_branding_options );
207
+ }
208
+
209
+ }
210
+
211
+ /**
212
+ * Migrate login customization settings.
213
+ *
214
+ * We don't need to use "is_changed" flag here because
215
+ * almost all Erident settings are about login customization.
216
+ */
217
+ private function migrate_login_settings() {
218
+
219
+ $udb_login_options = get_option( 'udb_login', [] );
220
+ $erident_options = get_option( 'plugin_erident_settings', [] );
221
+
222
+ if ( empty( $erident_options ) ) {
223
+ return;
224
+ }
225
+
226
+ $logo_image_url = isset( $erident_options['dashboard_image_logo'] ) && ! empty( $erident_options['dashboard_image_logo'] ) ? $erident_options['dashboard_image_logo'] : '';
227
+
228
+ if ( $logo_image_url ) {
229
+ $udb_login_options['logo_image'] = $logo_image_url;
230
+ }
231
+
232
+ $logo_width = isset( $erident_options['dashboard_image_logo_width'] ) && ! empty( $erident_options['dashboard_image_logo_width'] ) ? $erident_options['dashboard_image_logo_width'] : '';
233
+
234
+ if ( $logo_width ) {
235
+ $logo_width = trim( $logo_width ) . 'px';
236
+
237
+ // Logo width doesn't exist in UDB login customizer, but let's keep this.
238
+ $udb_login_options['logo_width'] = $logo_width;
239
+ }
240
+
241
+ $logo_height = isset( $erident_options['dashboard_image_logo_height'] ) && ! empty( $erident_options['dashboard_image_logo_height'] ) ? $erident_options['dashboard_image_logo_height'] : '';
242
+
243
+ if ( $logo_height ) {
244
+ $logo_height = trim( $logo_height ) . 'px';
245
+
246
+ $udb_login_options['logo_height'] = $logo_height;
247
+ }
248
+
249
+ $logo_text = isset( $erident_options['dashboard_power_text'] ) && ! empty( $erident_options['dashboard_power_text'] ) ? $erident_options['dashboard_power_text'] : '';
250
+
251
+ if ( $logo_text ) {
252
+ $udb_login_options['logo_title'] = $logo_text;
253
+ }
254
+
255
+ $bg_color = isset( $erident_options['top_bg_color'] ) && ! empty( $erident_options['top_bg_color'] ) ? $erident_options['top_bg_color'] : '';
256
+
257
+ if ( $bg_color ) {
258
+ $udb_login_options['bg_color'] = $bg_color;
259
+ }
260
+
261
+ $bg_image_url = isset( $erident_options['top_bg_image'] ) && ! empty( $erident_options['top_bg_image'] ) ? $erident_options['top_bg_image'] : '';
262
+
263
+ if ( $bg_image_url ) {
264
+ $udb_login_options['bg_image'] = $bg_image_url;
265
+ }
266
+
267
+ $bg_repeat = isset( $erident_options['top_bg_repeat'] ) && ! empty( $erident_options['top_bg_repeat'] ) ? $erident_options['top_bg_repeat'] : '';
268
+
269
+ if ( $bg_repeat ) {
270
+ $udb_login_options['bg_repeat'] = $bg_repeat;
271
+ }
272
+
273
+ $horizontal_bg_pos = isset( $erident_options['top_bg_xpos'] ) && ! empty( $erident_options['top_bg_xpos'] ) ? $erident_options['top_bg_xpos'] : '';
274
+ $horizontal_bg_pos = trim( $horizontal_bg_pos );
275
+
276
+ $vertical_bg_pos = isset( $erident_options['top_bg_ypos'] ) && ! empty( $erident_options['top_bg_ypos'] ) ? $erident_options['top_bg_ypos'] : '';
277
+ $vertical_bg_pos = trim( $vertical_bg_pos );
278
+
279
+ $bg_position = $horizontal_bg_pos . ' ' . $vertical_bg_pos;
280
+ $bg_custom_position = '';
281
+
282
+ $udb_bg_positions = array(
283
+ 'left top',
284
+ 'left center',
285
+ 'left bottom',
286
+ 'center top',
287
+ 'center center',
288
+ 'center bottom',
289
+ 'right top',
290
+ 'right center',
291
+ 'right bottom',
292
+ 'custom',
293
+ );
294
+
295
+ if ( ! in_array( $bg_position, $udb_bg_positions, true ) ) {
296
+ $bg_custom_position = $bg_position;
297
+ $bg_position = 'custom';
298
+ }
299
+
300
+ if ( $bg_position ) {
301
+ $udb_login_options['bg_position'] = $bg_position;
302
+ }
303
+
304
+ if ( $bg_custom_position ) {
305
+ $udb_login_options['bg_custom_position'] = $bg_custom_position;
306
+ }
307
+
308
+ $bg_size = isset( $erident_options['top_bg_size'] ) && ! empty( $erident_options['top_bg_size'] ) ? $erident_options['top_bg_size'] : '';
309
+ $bg_custom_size = '';
310
+
311
+ $udb_bg_sizes = array(
312
+ 'auto',
313
+ 'cover',
314
+ 'contain',
315
+ 'custom',
316
+ );
317
+
318
+ if ( ! in_array( $bg_size, $udb_bg_sizes, true ) ) {
319
+ $bg_custom_size = $bg_position;
320
+ $bg_size = 'custom';
321
+ }
322
+
323
+ if ( $bg_size ) {
324
+ $udb_login_options['bg_size'] = $bg_size;
325
+ }
326
+
327
+ if ( $bg_custom_size ) {
328
+ $udb_login_options['bg_custom_size'] = $bg_custom_size;
329
+ }
330
+
331
+ $form_width = isset( $erident_options['dashboard_login_width'] ) && ! empty( $erident_options['dashboard_login_width'] ) ? $erident_options['dashboard_login_width'] : '';
332
+
333
+ if ( $form_width ) {
334
+ $form_width = trim( $form_width ) . 'px';
335
+
336
+ $udb_login_options['form_width'] = $form_width;
337
+ }
338
+
339
+ $form_border_radius = isset( $erident_options['dashboard_login_radius'] ) && ! empty( $erident_options['dashboard_login_radius'] ) ? $erident_options['dashboard_login_radius'] : '';
340
+
341
+ if ( $form_border_radius ) {
342
+ $form_border_radius = trim( $form_border_radius ) . 'px';
343
+
344
+ $udb_login_options['form_border_radius'] = $form_border_radius;
345
+ }
346
+
347
+ $form_border_width = isset( $erident_options['dashboard_border_thick'] ) && ! empty( $erident_options['dashboard_border_thick'] ) ? $erident_options['dashboard_border_thick'] : '';
348
+
349
+ if ( $form_border_width ) {
350
+ $form_border_width = trim( $form_border_width ) . 'px';
351
+
352
+ $udb_login_options['form_border_width'] = $form_border_width;
353
+ }
354
+
355
+ $form_border_style = isset( $erident_options['dashboard_login_border'] ) && ! empty( $erident_options['dashboard_login_border'] ) ? $erident_options['dashboard_login_border'] : '';
356
+
357
+ if ( $form_border_style ) {
358
+ $udb_login_options['form_border_style'] = $form_border_style;
359
+ }
360
+
361
+ $form_border_color = isset( $erident_options['dashboard_border_color'] ) && ! empty( $erident_options['dashboard_border_color'] ) ? $erident_options['dashboard_border_color'] : '';
362
+
363
+ if ( $form_border_color ) {
364
+ $udb_login_options['form_border_color'] = $form_border_color;
365
+ }
366
+
367
+ $enable_form_shadow = isset( $erident_options['dashboard_check_form_shadow'] ) ? $erident_options['dashboard_check_form_shadow'] : 0;
368
+ $enable_form_shadow = 'yes' === strtolower( $enable_form_shadow ) ? 1 : $enable_form_shadow;
369
+ $enable_form_shadow = 'no' === strtolower( $enable_form_shadow ) ? 0 : $enable_form_shadow;
370
+ $enable_form_shadow = absint( $enable_form_shadow );
371
+
372
+ if ( $enable_form_shadow ) {
373
+ $udb_login_options['enable_form_shadow'] = 1;
374
+ }
375
+
376
+ $form_shadow_color = isset( $erident_options['dashboard_form_shadow'] ) && ! empty( $erident_options['dashboard_form_shadow'] ) ? $erident_options['dashboard_form_shadow'] : '';
377
+
378
+ if ( $form_shadow_color ) {
379
+ $udb_login_options['form_shadow_color'] = $form_shadow_color;
380
+ }
381
+
382
+ $form_bg_color = isset( $erident_options['dashboard_login_bg'] ) && ! empty( $erident_options['dashboard_login_bg'] ) ? $erident_options['dashboard_login_bg'] : '';
383
+
384
+ if ( isset( $erident_options['dashboard_login_bg_opacity'] ) ) {
385
+ // This `dashboard_login_bg_opacity` won't be used anymore since we use colorpicker alpha now.
386
+ $form_bg_opacity = '' !== $erident_options['dashboard_login_bg_opacity'] ? $erident_options['dashboard_login_bg_opacity'] : 1; // 0 is allowed here.
387
+
388
+ if ( false === stripos( $form_bg_color, 'rgba' ) && 1 > $form_bg_opacity ) {
389
+ $form_bg_color = \ariColor::newColor( $form_bg_color );
390
+ $form_bg_color = $form_bg_color->getNew( 'alpha', $form_bg_opacity )->toCSS( 'rgba' );
391
+ }
392
+ }
393
+
394
+ if ( $form_bg_color ) {
395
+ $udb_login_options['form_bg_color'] = $form_bg_color;
396
+ }
397
+
398
+ $form_bg_image_url = isset( $erident_options['login_bg_image'] ) && ! empty( $erident_options['login_bg_image'] ) ? $erident_options['login_bg_image'] : '';
399
+
400
+ if ( $form_bg_image_url ) {
401
+ $udb_login_options['form_bg_image'] = $form_bg_image_url;
402
+ }
403
+
404
+ $form_bg_repeat = isset( $erident_options['login_bg_repeat'] ) && ! empty( $erident_options['login_bg_repeat'] ) ? $erident_options['login_bg_repeat'] : '';
405
+
406
+ if ( $form_bg_repeat ) {
407
+ $udb_login_options['form_bg_repeat'] = $form_bg_repeat;
408
+ }
409
+
410
+ $form_horizontal_bg_pos = isset( $erident_options['login_bg_xpos'] ) && ! empty( $erident_options['login_bg_xpos'] ) ? $erident_options['login_bg_xpos'] : '';
411
+ $form_horizontal_bg_pos = trim( $form_horizontal_bg_pos );
412
+
413
+ $form_vertical_bg_pos = isset( $erident_options['login_bg_ypos'] ) && ! empty( $erident_options['login_bg_ypos'] ) ? $erident_options['login_bg_ypos'] : '';
414
+ $form_vertical_bg_pos = trim( $form_vertical_bg_pos );
415
+
416
+ $form_bg_position = $form_horizontal_bg_pos . ' ' . $form_horizontal_bg_pos;
417
+ $form_bg_custom_position = '';
418
+
419
+ if ( ! in_array( $form_bg_position, $udb_bg_positions, true ) ) {
420
+ $form_bg_custom_position = $form_bg_position;
421
+ $form_bg_position = 'custom';
422
+ }
423
+
424
+ if ( $form_bg_position ) {
425
+ $udb_login_options['form_bg_position'] = $form_bg_position;
426
+ }
427
+
428
+ if ( $form_bg_custom_position ) {
429
+ $udb_login_options['form_bg_custom_position'] = $form_bg_custom_position;
430
+ }
431
+
432
+ $labels_color = isset( $erident_options['dashboard_text_color'] ) && ! empty( $erident_options['dashboard_text_color'] ) ? $erident_options['dashboard_text_color'] : '';
433
+
434
+ if ( $labels_color ) {
435
+ $udb_login_options['labels_color'] = $labels_color;
436
+ }
437
+
438
+ $labels_font_size = isset( $erident_options['dashboard_label_text_size'] ) && ! empty( $erident_options['dashboard_label_text_size'] ) ? $erident_options['dashboard_label_text_size'] : '';
439
+
440
+ if ( $labels_font_size ) {
441
+ $labels_font_size = trim( $labels_font_size ) . 'px';
442
+
443
+ $udb_login_options['labels_font_size'] = $labels_font_size;
444
+ }
445
+
446
+ $fields_text_color = isset( $erident_options['dashboard_input_text_color'] ) && ! empty( $erident_options['dashboard_input_text_color'] ) ? $erident_options['dashboard_input_text_color'] : '';
447
+
448
+ if ( $fields_text_color ) {
449
+ $udb_login_options['fields_text_color'] = $fields_text_color;
450
+ $udb_login_options['fields_text_color_focus'] = $fields_text_color;
451
+ }
452
+
453
+ $fields_font_size = isset( $erident_options['dashboard_input_text_size'] ) && ! empty( $erident_options['dashboard_input_text_size'] ) ? $erident_options['dashboard_input_text_size'] : '';
454
+
455
+ if ( $fields_font_size ) {
456
+ $fields_font_size = trim( $fields_font_size ) . 'px';
457
+
458
+ $udb_login_options['fields_font_size'] = $fields_font_size;
459
+ }
460
+
461
+ $button_bg_color = isset( $erident_options['dashboard_button_color'] ) && ! empty( $erident_options['dashboard_button_color'] ) ? $erident_options['dashboard_button_color'] : '';
462
+ $button_bg_color_hover = '';
463
+
464
+ if ( $button_bg_color ) {
465
+ $button_bg_color_hover = \ariColor::newColor( $button_bg_color );
466
+ $button_bg_color_hover = $button_bg_color_hover->getNew( 'alpha', 0.9 )->toCSS( 'rgba' );
467
+
468
+ $udb_login_options['button_bg_color'] = $button_bg_color;
469
+ $udb_login_options['button_bg_color_hover'] = $button_bg_color_hover;
470
+ }
471
+
472
+ $button_text_color = isset( $erident_options['dashboard_button_text_color'] ) && ! empty( $erident_options['dashboard_button_text_color'] ) ? $erident_options['dashboard_button_text_color'] : '';
473
+
474
+ if ( $button_text_color ) {
475
+ $udb_login_options['button_text_color'] = $button_text_color;
476
+ $udb_login_options['button_text_color_hover'] = $button_text_color;
477
+ }
478
+
479
+ $footer_link_color = isset( $erident_options['dashboard_link_color'] ) && ! empty( $erident_options['dashboard_link_color'] ) ? $erident_options['dashboard_link_color'] : '';
480
+
481
+ if ( $footer_link_color ) {
482
+ $udb_login_options['footer_link_color'] = $footer_link_color;
483
+ $udb_login_options['footer_link_color_hover'] = $footer_link_color;
484
+ }
485
+
486
+ $enable_link_shadow = isset( $erident_options['dashboard_check_shadow'] ) ? $erident_options['dashboard_check_shadow'] : 0;
487
+ $enable_link_shadow = 'yes' === strtolower( $enable_link_shadow ) ? 1 : $enable_link_shadow;
488
+ $enable_link_shadow = 'no' === strtolower( $enable_link_shadow ) ? 0 : $enable_link_shadow;
489
+ $enable_link_shadow = absint( $enable_link_shadow );
490
+
491
+ if ( $enable_link_shadow ) {
492
+ // Enable link shadow doesn't exist in UDB login customizer, but let's keep this.
493
+ $udb_login_options['enable_link_shadow'] = 1;
494
+ }
495
+
496
+ $link_shadow_color = isset( $erident_options['dashboard_link_shadow'] ) && ! empty( $erident_options['dashboard_link_shadow'] ) ? $erident_options['dashboard_link_shadow'] : '';
497
+
498
+ if ( $link_shadow_color ) {
499
+ // Link shadow color doesn't exist in UDB login customizer, but let's keep this.
500
+ $udb_login_options['link_shadow_color'] = $link_shadow_color;
501
+ }
502
+
503
+ $remove_register_link = isset( $erident_options['dashboard_check_lost_pass'] ) ? $erident_options['dashboard_check_lost_pass'] : 0;
504
+ $remove_register_link = 'yes' === strtolower( $remove_register_link ) ? 1 : $remove_register_link;
505
+ $remove_register_link = 'no' === strtolower( $remove_register_link ) ? 0 : $remove_register_link;
506
+ $remove_register_link = absint( $remove_register_link );
507
+
508
+ if ( $remove_register_link ) {
509
+ $udb_login_options['remove_register_lost_pw_link'] = 1;
510
+ }
511
+
512
+ $remove_back_to_blog_link = isset( $erident_options['dashboard_check_backtoblog'] ) ? $erident_options['dashboard_check_backtoblog'] : 0;
513
+ $remove_back_to_blog_link = 'yes' === strtolower( $remove_back_to_blog_link ) ? 1 : $remove_back_to_blog_link;
514
+ $remove_back_to_blog_link = 'no' === strtolower( $remove_back_to_blog_link ) ? 0 : $remove_back_to_blog_link;
515
+ $remove_back_to_blog_link = absint( $remove_back_to_blog_link );
516
+
517
+ if ( $remove_back_to_blog_link ) {
518
+ $udb_login_options['remove_back_to_site_link'] = 1;
519
+ }
520
+
521
+ update_option( 'udb_login', $udb_login_options );
522
+
523
+ }
524
+
525
+ }
assets/css/migration.css ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @-webkit-keyframes cldashboardLoadingSpinAround {
2
+ from {
3
+ transform: rotate(0);
4
+ }
5
+ to {
6
+ transform: rotate(359deg);
7
+ }
8
+ }
9
+
10
+ @keyframes cldashboardLoadingSpinAround {
11
+ from {
12
+ transform: rotate(0);
13
+ }
14
+ to {
15
+ transform: rotate(359deg);
16
+ }
17
+ }
18
+
19
+ /**
20
+ * --------------------------------------------------
21
+ * Migration Notice
22
+ * --------------------------------------------------
23
+ */
24
+ .cldashboard-migration-notice {
25
+ padding: 25px 20px;
26
+ }
27
+
28
+ .cldashboard-migration-notice .notice-body {
29
+ display: flex;
30
+ }
31
+
32
+ .cldashboard-migration-notice .notice-icon {
33
+ padding-right: 25px;
34
+ }
35
+
36
+ .cldashboard-migration-notice .notice-icon img {
37
+ max-width: 55px;
38
+ }
39
+
40
+ .cldashboard-migration-notice .notice-content {
41
+ width: 100%;
42
+ }
43
+
44
+ .cldashboard-migration-notice .notice-content h2 {
45
+ margin-top: 0;
46
+ margin-bottom: 10px;
47
+ font-weight: 700;
48
+ }
49
+
50
+ .cldashboard-migration-notice .notice-content > p {
51
+ margin-top: 0;
52
+ margin-bottom: 10px;
53
+ }
54
+
55
+ .cldashboard-migration-notice .notice-content > p:last-child {
56
+ margin-bottom: 0;
57
+ }
58
+
59
+ /**
60
+ * --------------------------------------------------
61
+ * Migration Status
62
+ * --------------------------------------------------
63
+ */
64
+ .cldashboard-migration-statuses {
65
+ margin-top: 7px;
66
+ margin-bottom: 8px;
67
+ }
68
+
69
+ .cldashboard-migration-status {
70
+ display: none;
71
+ margin-bottom: 3px;
72
+ }
73
+
74
+ .cldashboard-migration-status.migration-failed,
75
+ .cldashboard-migration-status.migration-failed i {
76
+ color: tomato;
77
+ }
78
+
79
+ .cldashboard-migration-status i {
80
+ color: rgb(39, 223, 39);
81
+ }
82
+
83
+ .cldashboard-migration-status.is-waiting {
84
+ display: block;
85
+ }
86
+
87
+ .cldashboard-migration-status.is-waiting i {
88
+ display: none;
89
+ }
90
+
91
+ .cldashboard-migration-status .loader {
92
+ display: none;
93
+ position: relative;
94
+ bottom: -4px;
95
+ margin-right: 5px;
96
+ width: 14px;
97
+ height: 14px;
98
+ align-items: center;
99
+ -webkit-user-select: none;
100
+ -moz-user-select: none;
101
+ -ms-user-select: none;
102
+ user-select: none;
103
+ }
104
+
105
+ .cldashboard-migration-status.is-waiting .loader {
106
+ display: inline-flex;
107
+ justify-content: center;
108
+ color: transparent !important;
109
+ pointer-events: none;
110
+ }
111
+
112
+ .cldashboard-migration-status.is-waiting .loader::after {
113
+ content: "";
114
+ position: absolute;
115
+ width: 1em;
116
+ display: block;
117
+ height: 1em;
118
+ border: 2px solid #bbb;
119
+ border-color: transparent transparent #aaa #aaa !important;
120
+ border-radius: 290486px;
121
+ -webkit-animation: cldashboardLoadingSpinAround 0.5s infinite linear;
122
+ animation: cldashboardLoadingSpinAround 0.5s infinite linear;
123
+ }
124
+
125
+ .cldashboard-migration-status.is-done {
126
+ display: block;
127
+ }
assets/images/before-after.png ADDED
Binary file
assets/js/migration.js ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Migrate from Erident Custom Login & Dashboard to Ultimate Dashboard.
3
+ */
4
+ (function ($) {
5
+ var isRequesting = false;
6
+ var loading = {};
7
+ var ajax = {};
8
+ var migrationButton;
9
+
10
+ var elms = {};
11
+
12
+ elms.migrationFailed = document.querySelector(
13
+ ".cldashboard-migration-status.migration-failed"
14
+ );
15
+
16
+ if (!elms.migrationFailed) return;
17
+
18
+ elms.errorMessage = elms.migrationFailed.querySelector(".error-message");
19
+
20
+ elms.uninstallOldPlugin = document.querySelector(
21
+ ".cldashboard-migration-status.cldashboard-uninstalled"
22
+ );
23
+
24
+ elms.uninstallOldPluginMsg =
25
+ elms.uninstallOldPlugin.querySelector(".process-message");
26
+
27
+ elms.installNewPlugin = document.querySelector(
28
+ ".cldashboard-migration-status.ultimate-dashboard-installed"
29
+ );
30
+
31
+ elms.installNewPluginMsg =
32
+ elms.installNewPlugin.querySelector(".process-message");
33
+
34
+ elms.activateNewPlugin = document.querySelector(
35
+ ".cldashboard-migration-status.ultimate-dashboard-activated"
36
+ );
37
+
38
+ elms.activateNewPluginMsg =
39
+ elms.activateNewPlugin.querySelector(".process-message");
40
+
41
+ /**
42
+ * Call the main functions here.
43
+ */
44
+ function init() {
45
+ $(document).on("click", ".cldashboard-migration-button", ajax.migration);
46
+ }
47
+
48
+ loading.start = function () {
49
+ migrationButton.classList.add("is-loading");
50
+ };
51
+
52
+ loading.stop = function () {
53
+ migrationButton.classList.remove("is-loading");
54
+ };
55
+
56
+ /**
57
+ * Send ajax request to save the settings.
58
+ */
59
+ ajax.migration = function (e) {
60
+ e.preventDefault();
61
+
62
+ var confirmMsg =
63
+ "Please don't leave this page until the migration is complete. Migrate now?";
64
+
65
+ if (!confirm(confirmMsg)) {
66
+ return;
67
+ }
68
+
69
+ if (!migrationButton) migrationButton = this;
70
+
71
+ if (isRequesting) return;
72
+ isRequesting = true;
73
+ loading.start();
74
+
75
+ var data = {};
76
+
77
+ data.action = "cldashboard_migration";
78
+ data.nonce = CldashboardMigration.nonces.migration;
79
+
80
+ data.old_plugin_slug = CldashboardMigration.oldPlugin.slug;
81
+ data.old_plugin_basename = CldashboardMigration.oldPlugin.basename;
82
+
83
+ data.new_plugin_slug = CldashboardMigration.newPlugin.slug;
84
+ data.new_plugin_basename = CldashboardMigration.newPlugin.basename;
85
+
86
+ elms.uninstallOldPluginMsg.innerHTML =
87
+ "Uninstalling Erident Custom Login & Dashboard plugin...";
88
+ elms.uninstallOldPlugin.classList.add("is-waiting");
89
+
90
+ elms.migrationFailed.classList.remove("is-done");
91
+
92
+ $.ajax({
93
+ url: ajaxurl,
94
+ type: "post",
95
+ dataType: "json",
96
+ data: data,
97
+ })
98
+ .done(function (r) {
99
+ // Error is handled in the "fail" callback.
100
+ if (!r.success) return;
101
+
102
+ elms.uninstallOldPluginMsg.innerHTML = r.data;
103
+ elms.uninstallOldPlugin.classList.remove("is-waiting");
104
+ elms.uninstallOldPlugin.classList.add("is-done");
105
+
106
+ elms.installNewPluginMsg.innerHTML =
107
+ "Installing Ultimate Dashboard plugin...";
108
+ elms.installNewPlugin.classList.add("is-waiting");
109
+
110
+ isRequesting = false;
111
+ installUltimateDashboard();
112
+ })
113
+ .fail(function (jqXHR) {
114
+ var errorMessage =
115
+ "Something went wrong. Are you connected to the internet?";
116
+
117
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
118
+ errorMessage = jqXHR.responseJSON.data;
119
+ }
120
+
121
+ elms.errorMessage.innerHTML = errorMessage;
122
+ elms.uninstallOldPlugin.classList.remove("is-waiting");
123
+ elms.migrationFailed.classList.add("is-done");
124
+ loading.stop();
125
+ isRequesting = false;
126
+ });
127
+ };
128
+
129
+ function installUltimateDashboard() {
130
+ if (isRequesting) return;
131
+ isRequesting = true;
132
+
133
+ wp.updates.installPlugin({
134
+ slug: CldashboardMigration.newPlugin.slug,
135
+ success: function () {
136
+ elms.installNewPluginMsg.innerHTML =
137
+ "Ultimate Dashboard plugin has been installed";
138
+ elms.installNewPlugin.classList.remove("is-waiting");
139
+ elms.installNewPlugin.classList.add("is-done");
140
+
141
+ elms.activateNewPluginMsg.innerHTML =
142
+ "Activating Ultimate Dashboard plugin...";
143
+ elms.activateNewPlugin.classList.add("is-waiting");
144
+
145
+ isRequesting = false;
146
+ activateUltimateDashboard();
147
+ },
148
+ error: function (jqXHR) {
149
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
150
+ elms.errorMessage.innerHTML = jqXHR.responseJSON.data;
151
+ }
152
+
153
+ elms.installNewPlugin.classList.remove("is-waiting");
154
+ elms.migrationFailed.classList.add("is-done");
155
+ loading.stop();
156
+ isRequesting = false;
157
+ },
158
+ });
159
+ }
160
+
161
+ function activateUltimateDashboard() {
162
+ if (isRequesting) return;
163
+ isRequesting = true;
164
+
165
+ $.ajax({
166
+ async: true,
167
+ type: "GET",
168
+ url: CldashboardMigration.newPlugin.activationUrl,
169
+ success: function () {
170
+ elms.activateNewPluginMsg.innerHTML =
171
+ "Ultimate Dashboard plugin has been activated";
172
+ elms.activateNewPlugin.classList.remove("is-waiting");
173
+ elms.activateNewPlugin.classList.add("is-done");
174
+
175
+ loading.stop();
176
+ isRequesting = false;
177
+
178
+ // Redirect to Ultimate Dashboard settings page.
179
+ window.location.replace(CldashboardMigration.redirectUrl);
180
+ },
181
+ error: function (jqXHR) {
182
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
183
+ elms.errorMessage.innerHTML = jqXHR.responseJSON.data;
184
+ }
185
+
186
+ elms.activateNewPlugin.classList.remove("is-waiting");
187
+ elms.migrationFailed.classList.add("is-done");
188
+ loading.stop();
189
+ isRequesting = false;
190
+ },
191
+ });
192
+ }
193
+
194
+ init();
195
+ })(jQuery);
assets/js/settings-page.js CHANGED
@@ -5,594 +5,599 @@
5
  * @return {Object}
6
  */
7
  (function ($) {
8
- /**
9
- * The settings form.
10
- *
11
- * @var HTMLElement
12
- */
13
- var form = document.querySelector(".cldashboard-settings-form");
14
-
15
- /**
16
- * The setting fields.
17
- *
18
- * @var NodeList
19
- */
20
- var fields = document.querySelectorAll(
21
- ".cldashboard-settings-form .general-setting-field"
22
- );
23
-
24
- /**
25
- * The submit button.
26
- *
27
- * @var HTMLElement
28
- */
29
- var submitButton = document.querySelector(".cldashboard-submit-button");
30
-
31
- /**
32
- * The reset button.
33
- *
34
- * @var HTMLElement
35
- */
36
- var resetButton = document.querySelector(".cldashboard-reset-button");
37
-
38
- /**
39
- * The load default values button.
40
- *
41
- * @var HTMLElement
42
- */
43
- var loadDefaultSettingsButton = document.querySelector(
44
- ".cldashboard-load-defaults-button"
45
- );
46
-
47
- /**
48
- * The submit notice div.
49
- *
50
- * @var HTMLElement
51
- */
52
- var submitNotice = document.querySelector(".cldashboard-submit-notice");
53
-
54
- /**
55
- * The reset notice div.
56
- *
57
- * @var HTMLElement
58
- */
59
- var resetNotice = document.querySelector(".cldashboard-reset-notice");
60
-
61
- /**
62
- * Whether or not the form is currently being submitted.
63
- */
64
- var isProcessing = false;
65
-
66
- /**
67
- * Initialize the module, call the main functions.
68
- *
69
- * This function is the only function that should be called on top level scope.
70
- * Other functions are called / hooked from this function.
71
- */
72
- function init() {
73
- setupColorPicker();
74
- setupTabsNavigation();
75
-
76
- var bgImageField = document.querySelector(".cldashboard-bg-image-field");
77
- if (bgImageField) setupMediaField(bgImageField);
78
-
79
- var logoImageField = document.querySelector(
80
- ".cldashboard-logo-image-field"
81
- );
82
- if (logoImageField) setupMediaField(logoImageField);
83
-
84
- setupChainingFields();
85
-
86
- if (form) form.addEventListener("submit", onSubmit);
87
- if (submitButton) submitButton.classList.add("cldashboard-button");
88
-
89
- if (resetButton) {
90
- resetButton.classList.add("cldashboard-button");
91
- resetButton.addEventListener("click", onReset);
92
- }
93
-
94
- if (loadDefaultSettingsButton) {
95
- loadDefaultSettingsButton.classList.add("cldashboard-button");
96
- loadDefaultSettingsButton.addEventListener(
97
- "click",
98
- onLoadDefaultSettings
99
- );
100
- }
101
- }
102
-
103
- /**
104
- * Setup color picker for color picker fields.
105
- */
106
- function setupColorPicker() {
107
- $(".color-picker-field").wpColorPicker({
108
- palettes: true,
109
- hide: true,
110
- });
111
- }
112
-
113
- /**
114
- * Setup the tabs navigation for settings page.
115
- */
116
- function setupTabsNavigation() {
117
- $(".heatbox-tab-nav-item").on("click", function () {
118
- $(".heatbox-tab-nav-item").removeClass("active");
119
- $(this).addClass("active");
120
-
121
- var link = this.querySelector("a");
122
-
123
- if (link.href.indexOf("#") === -1) return;
124
-
125
- var hashValue = link.href.substring(link.href.indexOf("#") + 1);
126
-
127
- if ("tools" === hashValue) {
128
- submitButton.classList.add("is-hidden");
129
- resetButton.classList.add("is-hidden");
130
- loadDefaultSettingsButton.classList.add("is-hidden");
131
- } else {
132
- submitButton.classList.remove("is-hidden");
133
- resetButton.classList.remove("is-hidden");
134
- loadDefaultSettingsButton.classList.remove("is-hidden");
135
- }
136
-
137
- $(".heatbox-form-container .heatbox-admin-panel").css("display", "none");
138
-
139
- $(".heatbox-form-container .cldashboard-" + hashValue + "-panel").css(
140
- "display",
141
- "block"
142
- );
143
- });
144
-
145
- window.addEventListener("load", function () {
146
- var hashValue = window.location.hash.substring(1);
147
- var currentActiveTabMenu;
148
-
149
- if (!hashValue) {
150
- currentActiveTabMenu = document.querySelector(
151
- ".heatbox-tab-nav-item.active"
152
- );
153
- hashValue = currentActiveTabMenu
154
- ? currentActiveTabMenu.dataset.tab
155
- : "";
156
- hashValue = hashValue ? hashValue : "login-screen";
157
- }
158
-
159
- if ("tools" === hashValue) {
160
- submitButton.classList.add("is-hidden");
161
- resetButton.classList.add("is-hidden");
162
- loadDefaultSettingsButton.classList.add("is-hidden");
163
- } else {
164
- submitButton.classList.remove("is-hidden");
165
- resetButton.classList.remove("is-hidden");
166
- loadDefaultSettingsButton.classList.remove("is-hidden");
167
- }
168
-
169
- $(".heatbox-tab-nav-item").removeClass("active");
170
- $(".heatbox-tab-nav-item.cldashboard-" + hashValue + "-panel").addClass(
171
- "active"
172
- );
173
-
174
- $(".heatbox-form-container .heatbox-admin-panel").css("display", "none");
175
-
176
- $(".heatbox-form-container .cldashboard-" + hashValue + "-panel").css(
177
- "display",
178
- "block"
179
- );
180
- });
181
- }
182
-
183
- /**
184
- * Setup media field.
185
- */
186
- function setupMediaField(field) {
187
- var wpMedia;
188
-
189
- wpMedia = wp
190
- .media({
191
- title: "Choose Background Image",
192
- button: {
193
- text: "Upload Image",
194
- },
195
- multiple: false, // Set this to true to allow multiple files to be selected
196
- })
197
- .on("select", function () {
198
- var attachment = wpMedia.state().get("selection").first().toJSON();
199
- field.value = attachment.url;
200
- field.dispatchEvent(new Event("change"));
201
- });
202
-
203
- var uploadButton = field.parentNode.querySelector(
204
- ".cldashboard-upload-button"
205
- );
206
-
207
- if (uploadButton) {
208
- uploadButton.addEventListener("click", function (e) {
209
- wpMedia.open();
210
- });
211
- }
212
-
213
- var clearButton = field.parentNode.querySelector(
214
- ".cldashboard-clear-button"
215
- );
216
-
217
- if (clearButton) {
218
- clearButton.addEventListener("click", function (e) {
219
- field.value = "";
220
- field.dispatchEvent(new Event("change"));
221
- });
222
- }
223
- }
224
-
225
- /**
226
- * Setup fields chaining/ dependency.
227
- */
228
- function setupChainingFields() {
229
- var selectors = [
230
- "[data-show-if-field]",
231
- "[data-hide-if-field]",
232
- "[data-show-if-field-checked]",
233
- "[data-show-if-field-unchecked]",
234
- ];
235
-
236
- selectors.forEach(function (selector) {
237
- var children = document.querySelectorAll(selector);
238
- if (!children.length) return;
239
-
240
- [].slice.call(children).forEach(function (child) {
241
- setupChainingEvent(child, selector);
242
- });
243
- });
244
- }
245
-
246
- /**
247
- * Setup fields chaining event.
248
- *
249
- * @param {HTMLElement} child The children element.
250
- * @param selector child The selector that belongs to the children element.
251
- */
252
- function setupChainingEvent(child, selector) {
253
- var parentName = child.getAttribute(
254
- selector.replace("[", "").replace("]", "")
255
- );
256
- var parentField = document.querySelector("#" + parentName);
257
-
258
- var shownDisplayType = window.getComputedStyle(child).display;
259
- shownDisplayType = shownDisplayType ? shownDisplayType : "block";
260
-
261
- checkChainingState(child, shownDisplayType, parentField);
262
-
263
- if (parentField.classList.contains("use-select2")) {
264
- $(parentField).on("change", function (e) {
265
- checkChainingState(child, shownDisplayType, parentField);
266
- });
267
- } else {
268
- parentField.addEventListener("change", function (e) {
269
- checkChainingState(child, shownDisplayType, parentField);
270
- });
271
- }
272
- }
273
-
274
- /**
275
- * Check the children state: shown or hidden.
276
- *
277
- * @param {HTMLElement} child The children element.
278
- * @param string shownDisplayType The display type of child when it's shown (e.g: "flex" or "block").
279
- * @param {HTMLElement} parent The parent/ dependency element.
280
- */
281
- function checkChainingState(child, shownDisplayType, parent) {
282
- var parentTagName = parent.tagName.toLocaleLowerCase();
283
-
284
- if (parentTagName === "input" && parent.type === "checkbox") {
285
- // Handle "data-show-if-field-checked".
286
- if (child.hasAttribute("data-show-if-field-checked")) {
287
- if (parent.checked) {
288
- child.style.display = shownDisplayType;
289
- } else {
290
- child.style.display = "none";
291
- }
292
- } else {
293
- // Handle "data-show-if-field-unchecked".
294
- if (!parent.checked) {
295
- child.style.display = shownDisplayType;
296
- } else {
297
- child.style.display = "none";
298
- }
299
- }
300
-
301
- return;
302
- }
303
-
304
- var wantedValue = child.hasAttribute("data-show-if-field")
305
- ? child.dataset.showIfValue
306
- : child.dataset.hideIfValue;
307
- var parentValue;
308
-
309
- if (parentTagName === "select") {
310
- if (parent.multiple) {
311
- parentValue = $(parent).val();
312
- wantedValue = JSON.parse(wantedValue);
313
- } else {
314
- if (parent.selectedIndex > -1) {
315
- parentValue = parent.options[parent.selectedIndex].value;
316
- }
317
- }
318
- } else {
319
- parentValue = parent.value;
320
- }
321
-
322
- // Handle "data-show-if-field".
323
- if (child.hasAttribute("data-show-if-field")) {
324
- if (parentValue === wantedValue) {
325
- child.style.display = shownDisplayType;
326
- } else {
327
- child.style.display = "none";
328
- }
329
- } else {
330
- // Handle "data-hide-if-field".
331
- if (JSON.stringify(parentValue) === JSON.stringify(wantedValue)) {
332
- child.style.display = "none";
333
- } else {
334
- child.style.display = shownDisplayType;
335
- }
336
- }
337
- }
338
-
339
- function startLoading(button) {
340
- if (button) button.classList.add("is-loading");
341
- }
342
-
343
- function stopLoading(button) {
344
- if (button) button.classList.remove("is-loading");
345
- }
346
-
347
- /**
348
- * Function to run on form submit.
349
- *
350
- * @param Event e The event object.
351
- */
352
- function onSubmit(e) {
353
- e.preventDefault();
354
- if (isProcessing) return;
355
- isProcessing = true;
356
- startLoading(submitButton);
357
-
358
- var data = {};
359
-
360
- [].slice.call(fields).forEach(function (field) {
361
- var value = false;
362
-
363
- if (field.tagName.toLowerCase() === "select") {
364
- if (field.multiple) {
365
- value = JSON.stringify($(field).val());
366
- } else {
367
- if (field.selectedIndex) {
368
- value = field.options[field.selectedIndex].value;
369
- } else {
370
- value = field.value;
371
- }
372
- }
373
- } else {
374
- if (field.type === "checkbox" || field.type === "radio") {
375
- if (field.checked) {
376
- value = field.value;
377
- }
378
- } else {
379
- value = field.value;
380
- }
381
- }
382
-
383
- if (value !== false) data[field.name] = value;
384
- });
385
-
386
- data.action = "cldashboard_save_settings";
387
- data.nonce = CustomLoginDashboard.nonces.saveSettings;
388
-
389
- $.ajax({
390
- url: ajaxurl,
391
- type: "POST",
392
- data: data,
393
- })
394
- .done(function (r) {
395
- if (!r || !r.success) return;
396
- submitNotice.classList.add("is-success");
397
- submitNotice.classList.remove("is-error");
398
- submitNotice.innerHTML = r.data;
399
- })
400
- .fail(function (jqXHR) {
401
- var errorMesssage = "Something went wrong";
402
-
403
- if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
404
- errorMesssage = jqXHR.responseJSON.data;
405
- }
406
-
407
- submitNotice.classList.remove("is-success");
408
- submitNotice.classList.add("is-error");
409
- submitNotice.innerHTML = errorMesssage;
410
- })
411
- .always(function () {
412
- submitNotice.classList.add("is-shown");
413
- isProcessing = false;
414
- stopLoading(submitButton);
415
-
416
- setTimeout(function () {
417
- submitNotice.classList.remove("is-shown");
418
- }, 3000);
419
- });
420
- }
421
-
422
- /**
423
- * Function to run on reset button press.
424
- *
425
- * @param Event e The event object.
426
- */
427
- function onReset(e) {
428
- e.preventDefault();
429
- if (!confirm(CustomLoginDashboard.dialogs.resetSettingsConfirmation))
430
- return;
431
- if (isProcessing) return;
432
- isProcessing = true;
433
- startLoading(resetButton);
434
-
435
- var data = {};
436
-
437
- data.action = "cldashboard_reset_settings";
438
- data.nonce = CustomLoginDashboard.nonces.resetSettings;
439
-
440
- $.ajax({
441
- url: ajaxurl,
442
- type: "POST",
443
- data: data,
444
- })
445
- .done(function (r) {
446
- if (!r || !r.success) return;
447
- resetForm();
448
- resetNotice.classList.add("is-success");
449
- resetNotice.classList.remove("is-error");
450
- resetNotice.innerHTML = r.data;
451
- })
452
- .fail(function (jqXHR) {
453
- var errorMesssage = "Something went wrong";
454
-
455
- if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
456
- errorMesssage = jqXHR.responseJSON.data;
457
- }
458
-
459
- resetNotice.classList.remove("is-success");
460
- resetNotice.classList.add("is-error");
461
- resetNotice.innerHTML = errorMesssage;
462
- })
463
- .always(function () {
464
- resetNotice.classList.add("is-shown");
465
- isProcessing = false;
466
- stopLoading(resetButton);
467
-
468
- setTimeout(function () {
469
- resetNotice.classList.remove("is-shown");
470
- resetNotice.innerHTML = "";
471
- }, 3000);
472
- });
473
- }
474
-
475
- /**
476
- * Reset the settings form.
477
- */
478
- function resetForm() {
479
- // This line alone doesn't reset the form :).
480
- form.reset();
481
-
482
- [].slice.call(fields).forEach(function (field) {
483
- if (field.tagName.toLowerCase() === "select") {
484
- if (field.multiple) {
485
- $(field).val([]);
486
- } else {
487
- field.selectedIndex = 0;
488
- }
489
- } else {
490
- if (field.type === "checkbox" || field.type === "radio") {
491
- field.checked = false;
492
- } else {
493
- field.value = "";
494
- }
495
- }
496
- });
497
-
498
- // Reset the color picker.
499
- // @link https://github.com/Automattic/Iris/issues/53
500
- $(".color-alpha").css("background-color", "");
501
- }
502
-
503
- /**
504
- * Function to run on load defaults button press.
505
- *
506
- * @param Event e The event object.
507
- */
508
- function onLoadDefaultSettings(e) {
509
- e.preventDefault();
510
- if (!confirm(CustomLoginDashboard.dialogs.loadDefaultSettingsConfirmation))
511
- return;
512
- if (isProcessing) return;
513
- isProcessing = true;
514
- startLoading(loadDefaultSettingsButton);
515
-
516
- var data = {};
517
-
518
- data.action = "cldashboard_load_default_settings";
519
- data.nonce = CustomLoginDashboard.nonces.loadDefaultSettings;
520
-
521
- $.ajax({
522
- url: ajaxurl,
523
- type: "POST",
524
- data: data,
525
- })
526
- .done(function (r) {
527
- if (!r || !r.success) return;
528
- populateForm(r.data.settings);
529
- resetNotice.classList.add("is-success");
530
- resetNotice.classList.remove("is-error");
531
- resetNotice.innerHTML = r.data.message;
532
- })
533
- .fail(function (jqXHR) {
534
- var errorMesssage = "Something went wrong";
535
-
536
- if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
537
- errorMesssage = jqXHR.responseJSON.data;
538
- }
539
-
540
- resetNotice.classList.remove("is-success");
541
- resetNotice.classList.add("is-error");
542
- resetNotice.innerHTML = errorMesssage;
543
- })
544
- .always(function () {
545
- resetNotice.classList.add("is-shown");
546
- isProcessing = false;
547
- stopLoading(loadDefaultSettingsButton);
548
-
549
- setTimeout(function () {
550
- resetNotice.classList.remove("is-shown");
551
- resetNotice.innerHTML = "";
552
- }, 3000);
553
- });
554
- }
555
-
556
- function populateForm(settings) {
557
- var value;
558
- var field;
559
- var colorPickerPreview;
560
-
561
- for (var fieldName in settings) {
562
- if (Object.hasOwnProperty.call(settings, fieldName)) {
563
- value = settings[fieldName];
564
- field = document.getElementById(fieldName);
565
-
566
- if (field) {
567
- if (field.tagName.toLowerCase() === "select") {
568
- if (field.multiple) {
569
- $(field).val(value);
570
- } else {
571
- field.value = value;
572
- }
573
- } else if (field.type === "checkbox" || field.type === "radio") {
574
- field.checked = value ? true : false;
575
- } else {
576
- field.value = value;
577
-
578
- if (field.classList.contains("color-picker-field")) {
579
- $(field).wpColorPicker("color", value);
580
-
581
- colorPickerPreview =
582
- field.parentNode.parentNode.parentNode.querySelector(
583
- ".color-alpha"
584
- );
585
-
586
- if (colorPickerPreview) {
587
- colorPickerPreview.style.backgroundColor = value;
588
- }
589
- }
590
- }
591
- }
592
- }
593
- }
594
- }
595
-
596
- // Run the module.
597
- init();
 
 
 
 
 
598
  })(jQuery);
5
  * @return {Object}
6
  */
7
  (function ($) {
8
+ /**
9
+ * The settings form.
10
+ *
11
+ * @var HTMLElement
12
+ */
13
+ var form = document.querySelector(".cldashboard-settings-form");
14
+
15
+ /**
16
+ * The setting fields.
17
+ *
18
+ * @var NodeList
19
+ */
20
+ var fields = document.querySelectorAll(
21
+ ".cldashboard-settings-form .general-setting-field"
22
+ );
23
+
24
+ /**
25
+ * The submit button.
26
+ *
27
+ * @var HTMLElement
28
+ */
29
+ var submitButton = document.querySelector(".cldashboard-submit-button");
30
+
31
+ /**
32
+ * The reset button.
33
+ *
34
+ * @var HTMLElement
35
+ */
36
+ var resetButton = document.querySelector(".cldashboard-reset-button");
37
+
38
+ /**
39
+ * The load default values button.
40
+ *
41
+ * @var HTMLElement
42
+ */
43
+ var loadDefaultSettingsButton = document.querySelector(
44
+ ".cldashboard-load-defaults-button"
45
+ );
46
+
47
+ /**
48
+ * The submit notice div.
49
+ *
50
+ * @var HTMLElement
51
+ */
52
+ var submitNotice = document.querySelector(".cldashboard-submit-notice");
53
+
54
+ /**
55
+ * The reset notice div.
56
+ *
57
+ * @var HTMLElement
58
+ */
59
+ var resetNotice = document.querySelector(".cldashboard-reset-notice");
60
+
61
+ /**
62
+ * Whether or not the form is currently being submitted.
63
+ */
64
+ var isProcessing = false;
65
+
66
+ /**
67
+ * Initialize the module, call the main functions.
68
+ *
69
+ * This function is the only function that should be called on top level scope.
70
+ * Other functions are called / hooked from this function.
71
+ */
72
+ function init() {
73
+ setupColorPicker();
74
+ setupTabsNavigation();
75
+
76
+ var bgImageField = document.querySelector(".cldashboard-bg-image-field");
77
+ if (bgImageField) setupMediaField(bgImageField);
78
+
79
+ var formBgImageField = document.querySelector(
80
+ ".cldashboard-form-bg-image-field"
81
+ );
82
+ if (formBgImageField) setupMediaField(formBgImageField);
83
+
84
+ var logoImageField = document.querySelector(
85
+ ".cldashboard-logo-image-field"
86
+ );
87
+ if (logoImageField) setupMediaField(logoImageField);
88
+
89
+ setupChainingFields();
90
+
91
+ if (form) form.addEventListener("submit", onSubmit);
92
+ if (submitButton) submitButton.classList.add("cldashboard-button");
93
+
94
+ if (resetButton) {
95
+ resetButton.classList.add("cldashboard-button");
96
+ resetButton.addEventListener("click", onReset);
97
+ }
98
+
99
+ if (loadDefaultSettingsButton) {
100
+ loadDefaultSettingsButton.classList.add("cldashboard-button");
101
+ loadDefaultSettingsButton.addEventListener(
102
+ "click",
103
+ onLoadDefaultSettings
104
+ );
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Setup color picker for color picker fields.
110
+ */
111
+ function setupColorPicker() {
112
+ $(".color-picker-field").wpColorPicker({
113
+ palettes: true,
114
+ hide: true,
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Setup the tabs navigation for settings page.
120
+ */
121
+ function setupTabsNavigation() {
122
+ $(".heatbox-tab-nav-item").on("click", function () {
123
+ $(".heatbox-tab-nav-item").removeClass("active");
124
+ $(this).addClass("active");
125
+
126
+ var link = this.querySelector("a");
127
+
128
+ if (link.href.indexOf("#") === -1) return;
129
+
130
+ var hashValue = link.href.substring(link.href.indexOf("#") + 1);
131
+
132
+ if ("tools" === hashValue) {
133
+ submitButton.classList.add("is-hidden");
134
+ resetButton.classList.add("is-hidden");
135
+ loadDefaultSettingsButton.classList.add("is-hidden");
136
+ } else {
137
+ submitButton.classList.remove("is-hidden");
138
+ resetButton.classList.remove("is-hidden");
139
+ loadDefaultSettingsButton.classList.remove("is-hidden");
140
+ }
141
+
142
+ $(".heatbox-form-container .heatbox-admin-panel").css("display", "none");
143
+
144
+ $(".heatbox-form-container .cldashboard-" + hashValue + "-panel").css(
145
+ "display",
146
+ "block"
147
+ );
148
+ });
149
+
150
+ window.addEventListener("load", function () {
151
+ var hashValue = window.location.hash.substring(1);
152
+ var currentActiveTabMenu;
153
+
154
+ if (!hashValue) {
155
+ currentActiveTabMenu = document.querySelector(
156
+ ".heatbox-tab-nav-item.active"
157
+ );
158
+ hashValue = currentActiveTabMenu
159
+ ? currentActiveTabMenu.dataset.tab
160
+ : "";
161
+ hashValue = hashValue ? hashValue : "login-screen";
162
+ }
163
+
164
+ if ("tools" === hashValue) {
165
+ submitButton.classList.add("is-hidden");
166
+ resetButton.classList.add("is-hidden");
167
+ loadDefaultSettingsButton.classList.add("is-hidden");
168
+ } else {
169
+ submitButton.classList.remove("is-hidden");
170
+ resetButton.classList.remove("is-hidden");
171
+ loadDefaultSettingsButton.classList.remove("is-hidden");
172
+ }
173
+
174
+ $(".heatbox-tab-nav-item").removeClass("active");
175
+ $(".heatbox-tab-nav-item.cldashboard-" + hashValue + "-panel").addClass(
176
+ "active"
177
+ );
178
+
179
+ $(".heatbox-form-container .heatbox-admin-panel").css("display", "none");
180
+
181
+ $(".heatbox-form-container .cldashboard-" + hashValue + "-panel").css(
182
+ "display",
183
+ "block"
184
+ );
185
+ });
186
+ }
187
+
188
+ /**
189
+ * Setup media field.
190
+ */
191
+ function setupMediaField(field) {
192
+ var wpMedia;
193
+
194
+ wpMedia = wp
195
+ .media({
196
+ title: "Choose Background Image",
197
+ button: {
198
+ text: "Upload Image",
199
+ },
200
+ multiple: false, // Set this to true to allow multiple files to be selected
201
+ })
202
+ .on("select", function () {
203
+ var attachment = wpMedia.state().get("selection").first().toJSON();
204
+ field.value = attachment.url;
205
+ field.dispatchEvent(new Event("change"));
206
+ });
207
+
208
+ var uploadButton = field.parentNode.querySelector(
209
+ ".cldashboard-upload-button"
210
+ );
211
+
212
+ if (uploadButton) {
213
+ uploadButton.addEventListener("click", function (e) {
214
+ wpMedia.open();
215
+ });
216
+ }
217
+
218
+ var clearButton = field.parentNode.querySelector(
219
+ ".cldashboard-clear-button"
220
+ );
221
+
222
+ if (clearButton) {
223
+ clearButton.addEventListener("click", function (e) {
224
+ field.value = "";
225
+ field.dispatchEvent(new Event("change"));
226
+ });
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Setup fields chaining/ dependency.
232
+ */
233
+ function setupChainingFields() {
234
+ var selectors = [
235
+ "[data-show-if-field]",
236
+ "[data-hide-if-field]",
237
+ "[data-show-if-field-checked]",
238
+ "[data-show-if-field-unchecked]",
239
+ ];
240
+
241
+ selectors.forEach(function (selector) {
242
+ var children = document.querySelectorAll(selector);
243
+ if (!children.length) return;
244
+
245
+ [].slice.call(children).forEach(function (child) {
246
+ setupChainingEvent(child, selector);
247
+ });
248
+ });
249
+ }
250
+
251
+ /**
252
+ * Setup fields chaining event.
253
+ *
254
+ * @param {HTMLElement} child The children element.
255
+ * @param selector child The selector that belongs to the children element.
256
+ */
257
+ function setupChainingEvent(child, selector) {
258
+ var parentName = child.getAttribute(
259
+ selector.replace("[", "").replace("]", "")
260
+ );
261
+ var parentField = document.querySelector("#" + parentName);
262
+
263
+ var shownDisplayType = window.getComputedStyle(child).display;
264
+ shownDisplayType = shownDisplayType ? shownDisplayType : "block";
265
+
266
+ checkChainingState(child, shownDisplayType, parentField);
267
+
268
+ if (parentField.classList.contains("use-select2")) {
269
+ $(parentField).on("change", function (e) {
270
+ checkChainingState(child, shownDisplayType, parentField);
271
+ });
272
+ } else {
273
+ parentField.addEventListener("change", function (e) {
274
+ checkChainingState(child, shownDisplayType, parentField);
275
+ });
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Check the children state: shown or hidden.
281
+ *
282
+ * @param {HTMLElement} child The children element.
283
+ * @param string shownDisplayType The display type of child when it's shown (e.g: "flex" or "block").
284
+ * @param {HTMLElement} parent The parent/ dependency element.
285
+ */
286
+ function checkChainingState(child, shownDisplayType, parent) {
287
+ var parentTagName = parent.tagName.toLocaleLowerCase();
288
+
289
+ if (parentTagName === "input" && parent.type === "checkbox") {
290
+ // Handle "data-show-if-field-checked".
291
+ if (child.hasAttribute("data-show-if-field-checked")) {
292
+ if (parent.checked) {
293
+ child.style.display = shownDisplayType;
294
+ } else {
295
+ child.style.display = "none";
296
+ }
297
+ } else {
298
+ // Handle "data-show-if-field-unchecked".
299
+ if (!parent.checked) {
300
+ child.style.display = shownDisplayType;
301
+ } else {
302
+ child.style.display = "none";
303
+ }
304
+ }
305
+
306
+ return;
307
+ }
308
+
309
+ var wantedValue = child.hasAttribute("data-show-if-field")
310
+ ? child.dataset.showIfValue
311
+ : child.dataset.hideIfValue;
312
+ var parentValue;
313
+
314
+ if (parentTagName === "select") {
315
+ if (parent.multiple) {
316
+ parentValue = $(parent).val();
317
+ wantedValue = JSON.parse(wantedValue);
318
+ } else {
319
+ if (parent.selectedIndex > -1) {
320
+ parentValue = parent.options[parent.selectedIndex].value;
321
+ }
322
+ }
323
+ } else {
324
+ parentValue = parent.value;
325
+ }
326
+
327
+ // Handle "data-show-if-field".
328
+ if (child.hasAttribute("data-show-if-field")) {
329
+ if (parentValue === wantedValue) {
330
+ child.style.display = shownDisplayType;
331
+ } else {
332
+ child.style.display = "none";
333
+ }
334
+ } else {
335
+ // Handle "data-hide-if-field".
336
+ if (JSON.stringify(parentValue) === JSON.stringify(wantedValue)) {
337
+ child.style.display = "none";
338
+ } else {
339
+ child.style.display = shownDisplayType;
340
+ }
341
+ }
342
+ }
343
+
344
+ function startLoading(button) {
345
+ if (button) button.classList.add("is-loading");
346
+ }
347
+
348
+ function stopLoading(button) {
349
+ if (button) button.classList.remove("is-loading");
350
+ }
351
+
352
+ /**
353
+ * Function to run on form submit.
354
+ *
355
+ * @param Event e The event object.
356
+ */
357
+ function onSubmit(e) {
358
+ e.preventDefault();
359
+ if (isProcessing) return;
360
+ isProcessing = true;
361
+ startLoading(submitButton);
362
+
363
+ var data = {};
364
+
365
+ [].slice.call(fields).forEach(function (field) {
366
+ var value = false;
367
+
368
+ if (field.tagName.toLowerCase() === "select") {
369
+ if (field.multiple) {
370
+ value = JSON.stringify($(field).val());
371
+ } else {
372
+ if (field.selectedIndex) {
373
+ value = field.options[field.selectedIndex].value;
374
+ } else {
375
+ value = field.value;
376
+ }
377
+ }
378
+ } else {
379
+ if (field.type === "checkbox" || field.type === "radio") {
380
+ if (field.checked) {
381
+ value = field.value;
382
+ }
383
+ } else {
384
+ value = field.value;
385
+ }
386
+ }
387
+
388
+ if (value !== false) data[field.name] = value;
389
+ });
390
+
391
+ data.action = "cldashboard_save_settings";
392
+ data.nonce = CustomLoginDashboard.nonces.saveSettings;
393
+
394
+ $.ajax({
395
+ url: ajaxurl,
396
+ type: "POST",
397
+ data: data,
398
+ })
399
+ .done(function (r) {
400
+ if (!r || !r.success) return;
401
+ submitNotice.classList.add("is-success");
402
+ submitNotice.classList.remove("is-error");
403
+ submitNotice.innerHTML = r.data;
404
+ })
405
+ .fail(function (jqXHR) {
406
+ var errorMesssage = "Something went wrong";
407
+
408
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
409
+ errorMesssage = jqXHR.responseJSON.data;
410
+ }
411
+
412
+ submitNotice.classList.remove("is-success");
413
+ submitNotice.classList.add("is-error");
414
+ submitNotice.innerHTML = errorMesssage;
415
+ })
416
+ .always(function () {
417
+ submitNotice.classList.add("is-shown");
418
+ isProcessing = false;
419
+ stopLoading(submitButton);
420
+
421
+ setTimeout(function () {
422
+ submitNotice.classList.remove("is-shown");
423
+ }, 3000);
424
+ });
425
+ }
426
+
427
+ /**
428
+ * Function to run on reset button press.
429
+ *
430
+ * @param Event e The event object.
431
+ */
432
+ function onReset(e) {
433
+ e.preventDefault();
434
+ if (!confirm(CustomLoginDashboard.dialogs.resetSettingsConfirmation))
435
+ return;
436
+ if (isProcessing) return;
437
+ isProcessing = true;
438
+ startLoading(resetButton);
439
+
440
+ var data = {};
441
+
442
+ data.action = "cldashboard_reset_settings";
443
+ data.nonce = CustomLoginDashboard.nonces.resetSettings;
444
+
445
+ $.ajax({
446
+ url: ajaxurl,
447
+ type: "POST",
448
+ data: data,
449
+ })
450
+ .done(function (r) {
451
+ if (!r || !r.success) return;
452
+ resetForm();
453
+ resetNotice.classList.add("is-success");
454
+ resetNotice.classList.remove("is-error");
455
+ resetNotice.innerHTML = r.data;
456
+ })
457
+ .fail(function (jqXHR) {
458
+ var errorMesssage = "Something went wrong";
459
+
460
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
461
+ errorMesssage = jqXHR.responseJSON.data;
462
+ }
463
+
464
+ resetNotice.classList.remove("is-success");
465
+ resetNotice.classList.add("is-error");
466
+ resetNotice.innerHTML = errorMesssage;
467
+ })
468
+ .always(function () {
469
+ resetNotice.classList.add("is-shown");
470
+ isProcessing = false;
471
+ stopLoading(resetButton);
472
+
473
+ setTimeout(function () {
474
+ resetNotice.classList.remove("is-shown");
475
+ resetNotice.innerHTML = "";
476
+ }, 3000);
477
+ });
478
+ }
479
+
480
+ /**
481
+ * Reset the settings form.
482
+ */
483
+ function resetForm() {
484
+ // This line alone doesn't reset the form :).
485
+ form.reset();
486
+
487
+ [].slice.call(fields).forEach(function (field) {
488
+ if (field.tagName.toLowerCase() === "select") {
489
+ if (field.multiple) {
490
+ $(field).val([]);
491
+ } else {
492
+ field.selectedIndex = 0;
493
+ }
494
+ } else {
495
+ if (field.type === "checkbox" || field.type === "radio") {
496
+ field.checked = false;
497
+ } else {
498
+ field.value = "";
499
+ }
500
+ }
501
+ });
502
+
503
+ // Reset the color picker.
504
+ // @link https://github.com/Automattic/Iris/issues/53
505
+ $(".color-alpha").css("background-color", "");
506
+ }
507
+
508
+ /**
509
+ * Function to run on load defaults button press.
510
+ *
511
+ * @param Event e The event object.
512
+ */
513
+ function onLoadDefaultSettings(e) {
514
+ e.preventDefault();
515
+ if (!confirm(CustomLoginDashboard.dialogs.loadDefaultSettingsConfirmation))
516
+ return;
517
+ if (isProcessing) return;
518
+ isProcessing = true;
519
+ startLoading(loadDefaultSettingsButton);
520
+
521
+ var data = {};
522
+
523
+ data.action = "cldashboard_load_default_settings";
524
+ data.nonce = CustomLoginDashboard.nonces.loadDefaultSettings;
525
+
526
+ $.ajax({
527
+ url: ajaxurl,
528
+ type: "POST",
529
+ data: data,
530
+ })
531
+ .done(function (r) {
532
+ if (!r || !r.success) return;
533
+ populateForm(r.data.settings);
534
+ resetNotice.classList.add("is-success");
535
+ resetNotice.classList.remove("is-error");
536
+ resetNotice.innerHTML = r.data.message;
537
+ })
538
+ .fail(function (jqXHR) {
539
+ var errorMesssage = "Something went wrong";
540
+
541
+ if (jqXHR.responseJSON && jqXHR.responseJSON.data) {
542
+ errorMesssage = jqXHR.responseJSON.data;
543
+ }
544
+
545
+ resetNotice.classList.remove("is-success");
546
+ resetNotice.classList.add("is-error");
547
+ resetNotice.innerHTML = errorMesssage;
548
+ })
549
+ .always(function () {
550
+ resetNotice.classList.add("is-shown");
551
+ isProcessing = false;
552
+ stopLoading(loadDefaultSettingsButton);
553
+
554
+ setTimeout(function () {
555
+ resetNotice.classList.remove("is-shown");
556
+ resetNotice.innerHTML = "";
557
+ }, 3000);
558
+ });
559
+ }
560
+
561
+ function populateForm(settings) {
562
+ var value;
563
+ var field;
564
+ var colorPickerPreview;
565
+
566
+ for (var fieldName in settings) {
567
+ if (Object.hasOwnProperty.call(settings, fieldName)) {
568
+ value = settings[fieldName];
569
+ field = document.getElementById(fieldName);
570
+
571
+ if (field) {
572
+ if (field.tagName.toLowerCase() === "select") {
573
+ if (field.multiple) {
574
+ $(field).val(value);
575
+ } else {
576
+ field.value = value;
577
+ }
578
+ } else if (field.type === "checkbox" || field.type === "radio") {
579
+ field.checked = value ? true : false;
580
+ } else {
581
+ field.value = value;
582
+
583
+ if (field.classList.contains("color-picker-field")) {
584
+ $(field).wpColorPicker("color", value);
585
+
586
+ colorPickerPreview =
587
+ field.parentNode.parentNode.parentNode.querySelector(
588
+ ".color-alpha"
589
+ );
590
+
591
+ if (colorPickerPreview) {
592
+ colorPickerPreview.style.backgroundColor = value;
593
+ }
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+
601
+ // Run the module.
602
+ init();
603
  })(jQuery);
class-setup.php CHANGED
@@ -61,10 +61,15 @@ class Setup {
61
  add_action( 'admin_init', array( $this, 'process_export' ) );
62
  add_action( 'admin_init', array( $this, 'process_import' ) );
63
 
 
 
 
 
64
  // Ajax handlers.
65
  new Ajax\Save_Settings();
66
  new Ajax\Reset_Settings();
67
  new Ajax\Load_Default_Settings();
 
68
 
69
  }
70
 
@@ -109,7 +114,7 @@ class Setup {
109
  */
110
  public function add_submenu_page() {
111
 
112
- $page = add_options_page( __( 'Custom Login & Dashboard', 'erident-custom-login-and-dashboard' ), __( 'Custom Login & Dashboard', 'erident-custom-login-and-dashboard' ), 'administrator', 'erident-custom-login-and-dashboard', [ $this, 'page_output' ] );
113
 
114
  }
115
 
@@ -262,4 +267,144 @@ class Setup {
262
 
263
  }
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
61
  add_action( 'admin_init', array( $this, 'process_export' ) );
62
  add_action( 'admin_init', array( $this, 'process_import' ) );
63
 
64
+ // Migration stuff.
65
+ add_action( 'admin_enqueue_scripts', array( $this, 'migration_notice_scripts' ) );
66
+ add_action( 'admin_notices', array( $this, 'migration_notice' ) );
67
+
68
  // Ajax handlers.
69
  new Ajax\Save_Settings();
70
  new Ajax\Reset_Settings();
71
  new Ajax\Load_Default_Settings();
72
+ new Ajax\Migration();
73
 
74
  }
75
 
114
  */
115
  public function add_submenu_page() {
116
 
117
+ add_options_page( __( 'Custom Login & Dashboard', 'erident-custom-login-and-dashboard' ), __( 'Custom Login & Dashboard', 'erident-custom-login-and-dashboard' ), 'administrator', 'erident-custom-login-and-dashboard', [ $this, 'page_output' ] );
118
 
119
  }
120
 
267
 
268
  }
269
 
270
+ /**
271
+ * Enqueue the migration scripts.
272
+ */
273
+ public function migration_notice_scripts() {
274
+
275
+ wp_enqueue_script('updates');
276
+
277
+ wp_enqueue_style( 'cldashboard-migration', CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL . '/assets/css/migration.css', array(), CUSTOM_LOGIN_DASHBOARD_PLUGIN_VERSION );
278
+
279
+ wp_enqueue_script( 'cldashboard-migration', CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL . '/assets/js/migration.js', array( 'jquery' ), CUSTOM_LOGIN_DASHBOARD_PLUGIN_VERSION, true );
280
+
281
+ $old_plugin_slug = 'erident-custom-login-and-dashboard';
282
+ $old_plugin_basename = $old_plugin_slug . '/er-custom-login.php';
283
+
284
+ $new_plugin_slug = 'ultimate-dashboard';
285
+ $new_plugin_basename = $new_plugin_slug . '/' . $new_plugin_slug . '.php';
286
+
287
+ $activation_url = add_query_arg(
288
+ array(
289
+ 'action' => 'activate',
290
+ 'plugin' => rawurlencode( $new_plugin_basename ),
291
+ 'plugin_status' => 'all',
292
+ 'paged' => '1',
293
+ '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $new_plugin_basename ),
294
+ ),
295
+ esc_url( network_admin_url( 'plugins.php' ) )
296
+ );
297
+
298
+ $js_objects = array(
299
+ 'redirectUrl' => admin_url( 'edit.php?post_type=udb_widgets&page=udb_plugin_onboarding' ),
300
+ 'oldPlugin' => [
301
+ 'slug' => $old_plugin_slug,
302
+ 'basename' => $old_plugin_basename,
303
+ ],
304
+ 'newPlugin' => [
305
+ 'slug' => $new_plugin_slug,
306
+ 'basename' => $new_plugin_basename,
307
+ 'activationUrl' => $activation_url,
308
+ ],
309
+ 'nonces' => array(
310
+ 'migration' => wp_create_nonce( 'cldashboard_nonce_migration' ),
311
+ ),
312
+ );
313
+
314
+ wp_localize_script(
315
+ 'cldashboard-migration',
316
+ 'CldashboardMigration',
317
+ $js_objects
318
+ );
319
+
320
+ }
321
+
322
+ /**
323
+ * Notice about migration to "Ultimate Dashboard".
324
+ */
325
+ public function migration_notice() {
326
+ ?>
327
+
328
+ <div class="notice notice-error cldashboard-migration-notice is-dismissible" style="border: 1px solid #e5e5e5;">
329
+
330
+ <div class="notice-body">
331
+ <div class="notice-icon">
332
+ <img src="<?php echo esc_url( CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL ); ?>/assets/images/erident-logo.png">
333
+ </div>
334
+ <div class="notice-content">
335
+ <h2 style="font-size: 24px; font-weight: 400;">Erident is now Ultimate Dashboard!</h2>
336
+
337
+ <p style="font-size: 16px; opacity: .7;">
338
+ Migrate to Ultimate Dashboard today & unlock more powerful features (for free)!
339
+ </p>
340
+
341
+ <hr style="border-color: #eee; border-top: none;">
342
+
343
+ <img style="max-width: 900px; width: 100%; margin-bottom: 10px;" src="<?php echo esc_url( CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL ); ?>/assets/images/before-after.png">
344
+
345
+ <p style="margin-bottom: -3px;">
346
+ <strong style="color: #1d2327; font-size: 16px;">What does this mean for me?</strong>
347
+ </p>
348
+
349
+ <p>
350
+ It means a much better (live editing) experience when customizing your WordPress login page!<br> Not only that, there will be even more options available for you to fully customize your login screen.
351
+ </p>
352
+
353
+ <p style="margin-bottom: -3px;">
354
+ <strong style="color: #1d2327; font-size: 16px;">What happens to my existing customizations?</strong>
355
+ </p>
356
+
357
+ <p>
358
+ Don't worry! Your existing settings will stay in place.<br> All Erident settings will be migrated over to Ultimate Dashboard.
359
+ </p>
360
+
361
+ <p style="margin-bottom: -3px;">
362
+ <strong style="color: #1d2327; font-size: 16px;">Why NOT just keep Erident?</strong>
363
+ </p>
364
+
365
+ <p style="color: tomato; font-weight: 700; opacity: .8;">
366
+ Erident Custom Login & Dashboard is no longer actively supported.<br> To keep getting feature-updates & security fixes please upgrade to Ultimate Dashboard.
367
+ </p>
368
+
369
+ <p>
370
+ Please click the button below to safely migrate to Ultimate Dashboard.
371
+ </p>
372
+
373
+ <p>
374
+ <a href="" style="padding: 10px 40px;" class="button button-primary cldashboard-button cldashboard-migration-button">
375
+ Start One-Click Migration
376
+ </a>
377
+ <a style="margin: 10px;" href="https://ultimatedashboard.io/blog/erident-custom-login-dashboard-is-now-ultimate-dashboard/?utm_source=erident&utm_medium=admin-notice&utm_campaign=udb" target="_blank">Read the announcement post</a>
378
+ </p>
379
+
380
+ <div class="cldashboard-migration-statuses">
381
+ <div class="cldashboard-migration-status migration-failed">
382
+ <i class="dashicons dashicons-no"></i>
383
+ <span>Migration failed:</span> <span class="error-message"></span>
384
+ </div>
385
+ <div class="cldashboard-migration-status cldashboard-uninstalled">
386
+ <span class="loader"></span>
387
+ <i class="dashicons dashicons-yes"></i>
388
+ <span class="process-message">Old Swift Control is uninstalled.</span>
389
+ </div>
390
+ <div class="cldashboard-migration-status ultimate-dashboard-installed">
391
+ <span class="loader"></span>
392
+ <i class="dashicons dashicons-yes"></i>
393
+ <span class="process-message">New Better Admin Bar is installed.</span>
394
+ </div>
395
+ <div class="cldashboard-migration-status ultimate-dashboard-activated">
396
+ <span class="loader"></span>
397
+ <i class="dashicons dashicons-yes"></i>
398
+ <span class="process-message">New Better Admin Bar is activated.</span>
399
+ </div>
400
+ </div>
401
+ </div>
402
+ </div>
403
+
404
+ </div>
405
+
406
+ <?php
407
+
408
+ }
409
+
410
  }
er-custom-login.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Fully customize the WordPress Login Screen.
6
  * Text Domain: erident-custom-login-and-dashboard
7
  * Domain Path: /languages
8
- * Version: 4.0.1
9
  * Author: David Vongries
10
  * Author URI: https://davidvongries.com/
11
  * License: GPL-3.0
@@ -17,7 +17,7 @@
17
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ) );
18
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL', rtrim( plugin_dir_url( __FILE__ ), '/' ) );
19
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
20
- define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_VERSION', '4.0.1' );
21
 
22
  load_plugin_textdomain( 'erident-custom-login-and-dashboard', false, basename( dirname( __FILE__ ) ) . '/languages/' );
23
 
@@ -33,6 +33,7 @@ require __DIR__ . '/helpers/class-import.php';
33
  require __DIR__ . '/ajax/class-save-settings.php';
34
  require __DIR__ . '/ajax/class-reset-settings.php';
35
  require __DIR__ . '/ajax/class-load-default-settings.php';
 
36
 
37
  // Required classes.
38
  require __DIR__ . '/class-setup.php';
5
  * Description: Fully customize the WordPress Login Screen.
6
  * Text Domain: erident-custom-login-and-dashboard
7
  * Domain Path: /languages
8
+ * Version: 4.1
9
  * Author: David Vongries
10
  * Author URI: https://davidvongries.com/
11
  * License: GPL-3.0
17
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ) );
18
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_URL', rtrim( plugin_dir_url( __FILE__ ), '/' ) );
19
  define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
20
+ define( 'CUSTOM_LOGIN_DASHBOARD_PLUGIN_VERSION', '4.1' );
21
 
22
  load_plugin_textdomain( 'erident-custom-login-and-dashboard', false, basename( dirname( __FILE__ ) ) . '/languages/' );
23
 
33
  require __DIR__ . '/ajax/class-save-settings.php';
34
  require __DIR__ . '/ajax/class-reset-settings.php';
35
  require __DIR__ . '/ajax/class-load-default-settings.php';
36
+ require __DIR__ . '/ajax/class-migration.php';
37
 
38
  // Required classes.
39
  require __DIR__ . '/class-setup.php';
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: davidvongries, libinvbabu
3
  Tags: login, customisation, admin, dashboard, customise, erident, custom login, form, logo, customize, branding, login customizer, CSS, admin login, white label, login background, custom login page
4
  Requires at least: 3.0.0
5
- Tested up to: 5.9
6
- Stable tag: 4.0.1
7
  Requires PHP: 5.6
8
  License: GPL-3.0 License
9
  License URI: https://oss.ninja/gpl-3.0?organization=David%20Vongries&project=Erident%20Custom%20Login%20and%20Dashboard
@@ -11,11 +11,13 @@ License URI: https://oss.ninja/gpl-3.0?organization=David%20Vongries&project=Eri
11
  Fully customize the WordPress Login Screen.
12
 
13
  == Description ==
14
- **Erident Custom Login and Dashboard** is the #1 rated Plugin to customize the WordPress Login Screen. It's a clean & minimalist way for you to fully customize almost all aspects of the WordPress Login Page.
15
 
16
- Create a custom WordPress login page with just a few clicks! All the settings to customize the WordPress login are located under Settings > Custom Login & Dashboard.
 
 
17
 
18
- Are you looking for a way to fully customize your WordPress admin area? Check out our **[Ultimate Dashboard](https://ultimatedashboard.io/?utm_source=erident&utm_medium=repository&utm_campaign=udb)** Plugin.
19
 
20
  === Features ===
21
  Here is a list of some of the features available in Erident Custom Login & Dashboard:
@@ -54,6 +56,10 @@ Yes! For more options and to fully customize the WordPress dashboard, check out
54
  4. Customized WordPress Login Screen (Example 2)
55
 
56
  == Changelog ==
 
 
 
 
57
  = 4.0.1 | April 29, 2022 =
58
  * Tweak: Added sidebar layout
59
  * Fixed: "Load Default Settings" button appeared on Tools page
2
  Contributors: davidvongries, libinvbabu
3
  Tags: login, customisation, admin, dashboard, customise, erident, custom login, form, logo, customize, branding, login customizer, CSS, admin login, white label, login background, custom login page
4
  Requires at least: 3.0.0
5
+ Tested up to: 6.0
6
+ Stable tag: 4.1
7
  Requires PHP: 5.6
8
  License: GPL-3.0 License
9
  License URI: https://oss.ninja/gpl-3.0?organization=David%20Vongries&project=Erident%20Custom%20Login%20and%20Dashboard
11
  Fully customize the WordPress Login Screen.
12
 
13
  == Description ==
14
+ **Caution: Erident Custom Login and Dashboard is now Ultimate Dashboard. Please install [Ultimate Dashboard](https://wordpress.org/plugins/ultimate-dashboard/) instead.**
15
 
16
+ **If you are an existing user of the Erident plugin you will be greeted with a 1-click migration to safely migrate from Erident to Ultimate Dashboard from your WordPress admin dashboard.**
17
+
18
+ Erident Custom Login and Dashboard is the #1 rated Plugin to customize the WordPress Login Screen. It's a clean & minimalist way for you to fully customize almost all aspects of the WordPress Login Page.
19
 
20
+ Create a custom WordPress login page with just a few clicks! All the settings to customize the WordPress login are located under Settings > Custom Login & Dashboard.
21
 
22
  === Features ===
23
  Here is a list of some of the features available in Erident Custom Login & Dashboard:
56
  4. Customized WordPress Login Screen (Example 2)
57
 
58
  == Changelog ==
59
+ = 4.1 | July 19, 2022 =
60
+ * Announcement: Erident Custom Login & Dashboard is now Ultimate Dashboard! You will be greeted with a 1-click migration to safely migrate from Erident to Ultimate Dashboard. Learn more about why we have made this decision in the announcement post - https://ultimatedashboard.io/blog/erident-custom-login-dashboard-is-now-ultimate-dashboard/
61
+ * Fixed: Form background image button didn't trigger the media popup
62
+
63
  = 4.0.1 | April 29, 2022 =
64
  * Tweak: Added sidebar layout
65
  * Fixed: "Load Default Settings" button appeared on Tools page