Version Description
- Export in backend and frontend now works using step by step process using client calls to avoid gateway timeouts and other kind of timing limits in very long process
- Addon for WP User Manager improved to avoid redirection loop
Download this release
Release Info
Developer | carazo |
Plugin | Import users from CSV with meta |
Version | 1.18 |
Comparing to | |
See all releases |
Code changes from version 1.17.9 to 1.18
- addons/wp-user-manager.php +10 -1
- assets/export.js +95 -0
- assets/style.css +48 -0
- classes/batch_exporter.php +654 -0
- classes/export.php +126 -323
- classes/frontend.php +15 -6
- classes/settings.php +15 -0
- import-users-from-csv-with-meta.php +5 -1
- readme.txt +6 -2
addons/wp-user-manager.php
CHANGED
@@ -9,8 +9,9 @@ class ACUI_WP_User_Manager{
|
|
9 |
function __construct(){
|
10 |
add_filter( 'acui_force_reset_password_edit_profile_url', array( $this, 'force_reset_password_edit_profile_url' ) );
|
11 |
add_filter( 'acui_force_reset_password_redirect_condition', array( $this, 'force_reset_password_redirect_condition' ), 10 , 1 );
|
12 |
-
add_action( 'wpum_account_page_content', array( $this, 'force_reset_password_notice' ),
|
13 |
add_action( 'wpum_after_user_password_recovery', array( $this, 'force_reset_save_account_details' ) );
|
|
|
14 |
}
|
15 |
|
16 |
function force_reset_password_edit_profile_url(){
|
@@ -36,5 +37,13 @@ class ACUI_WP_User_Manager{
|
|
36 |
function force_reset_save_account_details( $user_id ){
|
37 |
delete_user_meta( $user_id, 'acui_force_reset_password' );
|
38 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
new ACUI_WP_User_Manager();
|
9 |
function __construct(){
|
10 |
add_filter( 'acui_force_reset_password_edit_profile_url', array( $this, 'force_reset_password_edit_profile_url' ) );
|
11 |
add_filter( 'acui_force_reset_password_redirect_condition', array( $this, 'force_reset_password_redirect_condition' ), 10 , 1 );
|
12 |
+
add_action( 'wpum_account_page_content', array( $this, 'force_reset_password_notice' ), 1 );
|
13 |
add_action( 'wpum_after_user_password_recovery', array( $this, 'force_reset_save_account_details' ) );
|
14 |
+
add_action( 'wpum_account_page_content', array( $this, 'maybe_force_reset_save_account_details' ), 0 );
|
15 |
}
|
16 |
|
17 |
function force_reset_password_edit_profile_url(){
|
37 |
function force_reset_save_account_details( $user_id ){
|
38 |
delete_user_meta( $user_id, 'acui_force_reset_password' );
|
39 |
}
|
40 |
+
|
41 |
+
function maybe_force_reset_save_account_details(){
|
42 |
+
if( !isset( $_GET ) || empty( $_GET ) )
|
43 |
+
return;
|
44 |
+
|
45 |
+
if( isset( $_GET['password-updated'] ) && $_GET['password-updated'] == 'success' && isset( $_GET['tab'] ) && $_GET['tab'] == 'password' )
|
46 |
+
delete_user_meta( get_current_user_id(), 'acui_force_reset_password' );
|
47 |
+
}
|
48 |
}
|
49 |
new ACUI_WP_User_Manager();
|
assets/export.js
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
;(function ( $, window ) {
|
2 |
+
var userExportForm = function( $form ) {
|
3 |
+
this.$form = $form;
|
4 |
+
this.xhr = false;
|
5 |
+
|
6 |
+
this.$form.find( '.user-exporter-progress' ).val( 0 );
|
7 |
+
this.processStep = this.processStep.bind( this );
|
8 |
+
$form.on( 'submit', { userExportForm: this }, this.onSubmit );
|
9 |
+
};
|
10 |
+
|
11 |
+
userExportForm.prototype.onSubmit = function( event ) {
|
12 |
+
event.preventDefault();
|
13 |
+
|
14 |
+
$( "html, body" ).animate({ scrollTop: 0 }, "slow" );
|
15 |
+
|
16 |
+
var currentDate = new Date(),
|
17 |
+
day = currentDate.getDate(),
|
18 |
+
month = currentDate.getMonth() + 1,
|
19 |
+
year = currentDate.getFullYear(),
|
20 |
+
timestamp = currentDate.getTime(),
|
21 |
+
filename = 'user-export-' + day + '-' + month + '-' + year + '-' + timestamp + '.csv';
|
22 |
+
|
23 |
+
event.data.userExportForm.$form.addClass( 'user-exporter__exporting' );
|
24 |
+
event.data.userExportForm.$form.find( '.user-exporter-progress' ).val( 0 );
|
25 |
+
event.data.userExportForm.$form.find( '.user-exporter-progress-value' ).text( acui_export_js_object.starting_process + " - 0%" );
|
26 |
+
event.data.userExportForm.processStep( 1, $( this ).serialize(), '', filename );
|
27 |
+
};
|
28 |
+
|
29 |
+
userExportForm.prototype.processStep = function( step, data, filename ) {
|
30 |
+
var $this = this;
|
31 |
+
var frontend = $( '[name="acui_frontend_export"]' ).val();
|
32 |
+
var convert_timestamp, order_fields_alphabetically, double_encapsulate_serialized_values;
|
33 |
+
|
34 |
+
if( frontend == 1 ){
|
35 |
+
convert_timestamp = $this.$form.find( '[name="convert_timestamp"]' ).val();
|
36 |
+
order_fields_alphabetically = $this.$form.find( '[name="order_fields_alphabetically"]' ).val();
|
37 |
+
double_encapsulate_serialized_values = $this.$form.find( '[name="double_encapsulate_serialized_values"]' ).val();
|
38 |
+
}
|
39 |
+
else{
|
40 |
+
convert_timestamp = $this.$form.find( '[name="convert_timestamp"]' ).is( ":checked");
|
41 |
+
order_fields_alphabetically = $this.$form.find( '[name="order_fields_alphabetically"]' ).is( ":checked");
|
42 |
+
double_encapsulate_serialized_values = $this.$form.find( '[name="double_encapsulate_serialized_values"]' ).is( ":checked");
|
43 |
+
}
|
44 |
+
|
45 |
+
$.ajax( {
|
46 |
+
type: 'POST',
|
47 |
+
url: acui_export_js_object.ajaxurl,
|
48 |
+
data: {
|
49 |
+
form: data,
|
50 |
+
action: 'acui_export_users_csv',
|
51 |
+
step: step,
|
52 |
+
filename: filename,
|
53 |
+
delimiter: $this.$form.find( '[name="delimiter"]' ).val(),
|
54 |
+
role: $this.$form.find( '[name="role"]' ).val(),
|
55 |
+
from: $this.$form.find( '[name="from"]' ).val(),
|
56 |
+
to: $this.$form.find( '[name="to"]' ).val(),
|
57 |
+
convert_timestamp: convert_timestamp,
|
58 |
+
datetime_format: $this.$form.find( '[name="datetime_format"]' ).val(),
|
59 |
+
order_fields_alphabetically: order_fields_alphabetically,
|
60 |
+
double_encapsulate_serialized_values: double_encapsulate_serialized_values,
|
61 |
+
columns: $this.$form.find( '[name="columns"]' ).val(),
|
62 |
+
orderby: $this.$form.find( '[name="orderby"]' ).val(),
|
63 |
+
order: $this.$form.find( '[name="order"]' ).val(),
|
64 |
+
security: $this.$form.find( '#security' ).val(),
|
65 |
+
},
|
66 |
+
dataType: 'json',
|
67 |
+
success: function( response ) {
|
68 |
+
if ( response.success ) {
|
69 |
+
if ( 'done' === response.data.step ) {
|
70 |
+
$this.$form.find('.user-exporter-progress').val( response.data.percentage );
|
71 |
+
$this.$form.find('.user-exporter-progress-value').text( response.data.percentage + "%" );
|
72 |
+
window.location = response.data.url;
|
73 |
+
setTimeout( function() {
|
74 |
+
$this.$form.removeClass( 'user-exporter__exporting' );
|
75 |
+
$( '#acui_download_csv_wrapper > td > input' ).prop( 'disabled', false );
|
76 |
+
}, 2000 );
|
77 |
+
} else {
|
78 |
+
$this.$form.find( '.user-exporter-progress' ).val( response.data.percentage );
|
79 |
+
$this.$form.find( '.user-exporter-progress-value' ).text( acui_export_js_object.step + " " + response.data.step + " " + acui_export_js_object.of_approximately + " " + response.data.total_steps + " " + acui_export_js_object.steps + " - " + response.data.percentage + "%" );
|
80 |
+
$this.processStep( parseInt( response.data.step, 10 ), data, filename );
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
} ).fail( function( response ) {
|
85 |
+
window.console.log( response );
|
86 |
+
} );
|
87 |
+
};
|
88 |
+
|
89 |
+
$.fn.user_export_form = function() {
|
90 |
+
new userExportForm( this );
|
91 |
+
return this;
|
92 |
+
};
|
93 |
+
|
94 |
+
$( '#acui_exporter' ).user_export_form();
|
95 |
+
})( jQuery, window );
|
assets/style.css
CHANGED
@@ -87,4 +87,52 @@
|
|
87 |
background: none;
|
88 |
line-height: 1;
|
89 |
min-height: 13px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
87 |
background: none;
|
88 |
line-height: 1;
|
89 |
min-height: 13px;
|
90 |
+
}
|
91 |
+
|
92 |
+
#acui_exporter .user-exporter-progress-wrapper{
|
93 |
+
padding: 5px;
|
94 |
+
background-color: white;
|
95 |
+
width: 80%;
|
96 |
+
margin: 0 auto;
|
97 |
+
text-align: center;
|
98 |
+
}
|
99 |
+
|
100 |
+
#acui_exporter .user-exporter-progress{
|
101 |
+
width: 100%;
|
102 |
+
height: 42px;
|
103 |
+
border: 0;
|
104 |
+
border-radius: 9px;
|
105 |
+
}
|
106 |
+
.user-exporter-progress::-webkit-progress-bar {
|
107 |
+
background-color: #f3f3f3;
|
108 |
+
border-radius: 9px;
|
109 |
+
}
|
110 |
+
|
111 |
+
.user-exporter-progress::-webkit-progress-value {
|
112 |
+
background: #2271b1;
|
113 |
+
border-radius: 9px;
|
114 |
+
}
|
115 |
+
|
116 |
+
.user-exporter-progress::-moz-progress-bar {
|
117 |
+
background: #2271b1;
|
118 |
+
border-radius: 9px;
|
119 |
+
}
|
120 |
+
|
121 |
+
.user-exporter-progress .progress-value {
|
122 |
+
padding: 0px 5px;
|
123 |
+
line-height: 20px;
|
124 |
+
margin-left: 5px;
|
125 |
+
font-size: .8em;
|
126 |
+
color: #555;
|
127 |
+
height: 18px;
|
128 |
+
float: right;
|
129 |
+
}
|
130 |
+
|
131 |
+
#acui_exporter.user-exporter__exporting table,
|
132 |
+
#acui_exporter .user-exporter-progress-wrapper{
|
133 |
+
display: none;
|
134 |
+
}
|
135 |
+
|
136 |
+
#acui_exporter.user-exporter__exporting .user-exporter-progress-wrapper{
|
137 |
+
display: block;
|
138 |
}
|
classes/batch_exporter.php
ADDED
@@ -0,0 +1,654 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
+
class ACUI_Batch_Exporter{
|
8 |
+
protected $filename = 'user-export.csv';
|
9 |
+
protected $limit = 50;
|
10 |
+
protected $exported_row_count = 0;
|
11 |
+
protected $row_data = array();
|
12 |
+
protected $total_rows = 0;
|
13 |
+
protected $columns_to_export = array();
|
14 |
+
|
15 |
+
protected $page = 1;
|
16 |
+
protected $delimiter = ',';
|
17 |
+
protected $role = '';
|
18 |
+
protected $from = '';
|
19 |
+
protected $to = '';
|
20 |
+
protected $convert_timestamp = false;
|
21 |
+
protected $datetime_format;
|
22 |
+
protected $order_fields_alphabetically = false;
|
23 |
+
protected $double_encapsulate_serialized_values = false;
|
24 |
+
protected $filtered_columns = array();
|
25 |
+
protected $orderby = '';
|
26 |
+
protected $order = '';
|
27 |
+
|
28 |
+
protected $user_data;
|
29 |
+
protected $accepted_order_by;
|
30 |
+
protected $woocommerce_default_user_meta_keys;
|
31 |
+
protected $other_non_date_keys;
|
32 |
+
|
33 |
+
function __construct() {
|
34 |
+
add_filter( 'acui_export_non_date_keys', array( $this, 'get_non_date_keys' ), 1, 1 );
|
35 |
+
add_filter( 'acui_export_columns', array( $this, 'maybe_order_columns_alphabetacally' ), 10, 2 );
|
36 |
+
add_filter( 'acui_export_get_key_user_data', array( $this, 'filter_key_user_id' ) );
|
37 |
+
add_filter( 'acui_export_columns', array( $this, 'maybe_order_columns_filtered_columns_parameter' ), 11, 2 );
|
38 |
+
add_filter( 'acui_export_data', array( $this, 'maybe_double_encapsulate_serialized_values' ), 9 - 1, 5 );
|
39 |
+
add_filter( 'acui_export_data', array( $this, 'maybe_order_row_alphabetically' ), 10, 5 );
|
40 |
+
add_filter( 'acui_export_data', array( $this, 'maybe_order_row_filtered_columns_parameter' ), 11, 5 );
|
41 |
+
|
42 |
+
$this->user_data = array( "user_login", "user_email", "source_user_id", "user_pass", "user_nicename", "user_url", "user_registered", "display_name" );
|
43 |
+
$this->accepted_order_by = array( 'ID', 'display_name', 'name', 'user_name', 'login', 'user_login', 'nicename', 'user_nicename', 'email', 'user_email', 'url', 'user_url', 'registered', 'user_registered', 'post_count' );
|
44 |
+
$this->woocommerce_default_user_meta_keys = array( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone', 'billing_country', 'billing_address_1', 'billing_city', 'billing_state', 'billing_postcode', 'shipping_first_name', 'shipping_last_name', 'shipping_country', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode' );
|
45 |
+
$this->other_non_date_keys = array( 'shipping_phone', '_vat_number', '_billing_vat_number' );
|
46 |
+
$this->total_rows = $this->get_total_rows();
|
47 |
+
}
|
48 |
+
|
49 |
+
function get_non_date_keys( $non_date_keys ){
|
50 |
+
return array_merge( $non_date_keys, $this->user_data, $this->woocommerce_default_user_meta_keys, $this->other_non_date_keys );
|
51 |
+
}
|
52 |
+
|
53 |
+
function maybe_order_columns_alphabetacally( $row, $args ){
|
54 |
+
if( !$args['order_fields_alphabetically'] )
|
55 |
+
return $row;
|
56 |
+
|
57 |
+
$first_two_columns = array_slice( $row, 0, 2 );
|
58 |
+
$to_order_columns = array_unique( array_slice( $row, 2 ) );
|
59 |
+
sort( $to_order_columns, SORT_LOCALE_STRING );
|
60 |
+
|
61 |
+
return array_merge( $first_two_columns, $to_order_columns );
|
62 |
+
}
|
63 |
+
|
64 |
+
function filter_key_user_id( $key ){
|
65 |
+
return ( $key == 'source_user_id' ) ? 'ID' : $key;
|
66 |
+
}
|
67 |
+
|
68 |
+
function maybe_order_columns_filtered_columns_parameter( $row, $args ){
|
69 |
+
return ( !is_array( $args['filtered_columns'] ) || count( $args['filtered_columns'] ) == 0 ) ? $row : $args['filtered_columns'];
|
70 |
+
}
|
71 |
+
|
72 |
+
function maybe_order_row_alphabetically( $row, $user, $datetime_format, $columns, $args ){
|
73 |
+
if( !$args['order_fields_alphabetically'] )
|
74 |
+
return $row;
|
75 |
+
|
76 |
+
$row_sorted = array();
|
77 |
+
foreach( $columns as $field ){
|
78 |
+
$row_sorted[ $field ] = $row[ $field ];
|
79 |
+
}
|
80 |
+
|
81 |
+
return $row_sorted;
|
82 |
+
}
|
83 |
+
|
84 |
+
function maybe_order_row_filtered_columns_parameter( $row, $user, $datetime_format, $columns, $args ){
|
85 |
+
if( !is_array( $args['filtered_columns'] ) || count( $args['filtered_columns'] ) == 0 )
|
86 |
+
return $row;
|
87 |
+
|
88 |
+
$row_sorted = array();
|
89 |
+
foreach( $args['filtered_columns'] as $field ){
|
90 |
+
$row_sorted[ $field ] = $row[ $field ];
|
91 |
+
}
|
92 |
+
|
93 |
+
return $row_sorted;
|
94 |
+
}
|
95 |
+
|
96 |
+
function maybe_double_encapsulate_serialized_values( $row, $user, $datetime_format, $columns, $args ){
|
97 |
+
if( !$args['double_encapsulate_serialized_values'] )
|
98 |
+
return $row;
|
99 |
+
|
100 |
+
foreach( $columns as $field ){
|
101 |
+
if( is_serialized( $row[ $field ] ) )
|
102 |
+
$row[ $field ] = '"' . $row[ $field ] . '"';
|
103 |
+
}
|
104 |
+
|
105 |
+
return $row;
|
106 |
+
}
|
107 |
+
|
108 |
+
function load_columns(){
|
109 |
+
$row = array();
|
110 |
+
|
111 |
+
foreach ( $this->get_user_data() as $key ) {
|
112 |
+
$row[] = $key;
|
113 |
+
}
|
114 |
+
|
115 |
+
if( count( $this->get_filtered_columns() ) == 0 || in_array( 'role', $this->get_filtered_columns() ) )
|
116 |
+
$row[] = "role";
|
117 |
+
|
118 |
+
foreach ( $this->get_user_meta_keys() as $key ) {
|
119 |
+
$row[] = $key;
|
120 |
+
}
|
121 |
+
|
122 |
+
$this->set_columns_to_export( apply_filters( 'acui_export_columns', $row, array( 'order_fields_alphabetically' => $this->get_order_fields_alphabetically(), 'double_encapsulate_serialized_values' => $this->get_double_encapsulate_serialized_values(), 'filtered_columns' => $this->get_filtered_columns() ) ) );
|
123 |
+
}
|
124 |
+
|
125 |
+
function set_columns_to_export( $columns ) {
|
126 |
+
$this->columns_to_export = $columns;
|
127 |
+
}
|
128 |
+
|
129 |
+
function get_columns_to_export() {
|
130 |
+
return $this->columns_to_export;
|
131 |
+
}
|
132 |
+
|
133 |
+
function set_delimiter( $delimiter ){
|
134 |
+
switch ( $delimiter ) {
|
135 |
+
case 'COMMA':
|
136 |
+
$this->delimiter = ",";
|
137 |
+
break;
|
138 |
+
|
139 |
+
case 'COLON':
|
140 |
+
$this->delimiter = ":";
|
141 |
+
break;
|
142 |
+
|
143 |
+
case 'SEMICOLON':
|
144 |
+
$this->delimiter = ";";
|
145 |
+
break;
|
146 |
+
|
147 |
+
case 'TAB':
|
148 |
+
$this->delimiter = "\t";
|
149 |
+
break;
|
150 |
+
|
151 |
+
default:
|
152 |
+
$this->delimiter = ",";
|
153 |
+
break;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
function get_delimiter() {
|
158 |
+
return $this->delimiter;
|
159 |
+
}
|
160 |
+
|
161 |
+
function set_role( $role ){
|
162 |
+
$this->role = $role;
|
163 |
+
}
|
164 |
+
|
165 |
+
function get_role(){
|
166 |
+
return $this->role;
|
167 |
+
}
|
168 |
+
|
169 |
+
function set_from( $from ){
|
170 |
+
$this->from = $from;
|
171 |
+
}
|
172 |
+
|
173 |
+
function get_from(){
|
174 |
+
return $this->from;
|
175 |
+
}
|
176 |
+
|
177 |
+
function set_to( $to ){
|
178 |
+
$this->to = $to;
|
179 |
+
}
|
180 |
+
|
181 |
+
function get_to(){
|
182 |
+
return $this->to;
|
183 |
+
}
|
184 |
+
|
185 |
+
function set_convert_timestamp( $convert_timestamp ){
|
186 |
+
$this->convert_timestamp = filter_var( $convert_timestamp, FILTER_VALIDATE_BOOLEAN );
|
187 |
+
}
|
188 |
+
|
189 |
+
function get_convert_timestamp(){
|
190 |
+
return $this->convert_timestamp;
|
191 |
+
}
|
192 |
+
|
193 |
+
function set_datetime_format( $datetime_format ){
|
194 |
+
$this->datetime_format = $datetime_format;
|
195 |
+
}
|
196 |
+
|
197 |
+
function get_datetime_format(){
|
198 |
+
return $this->datetime_format;
|
199 |
+
}
|
200 |
+
|
201 |
+
function set_order_fields_alphabetically( $order_fields_alphabetically ){
|
202 |
+
$this->order_fields_alphabetically = filter_var( $order_fields_alphabetically, FILTER_VALIDATE_BOOLEAN );
|
203 |
+
}
|
204 |
+
|
205 |
+
function get_order_fields_alphabetically(){
|
206 |
+
return $this->order_fields_alphabetically;
|
207 |
+
}
|
208 |
+
|
209 |
+
function set_double_encapsulate_serialized_values( $double_encapsulate_serialized_values ){
|
210 |
+
$this->double_encapsulate_serialized_values = filter_var( $double_encapsulate_serialized_values, FILTER_VALIDATE_BOOLEAN );
|
211 |
+
}
|
212 |
+
|
213 |
+
function get_double_encapsulate_serialized_values(){
|
214 |
+
return $this->double_encapsulate_serialized_values;
|
215 |
+
}
|
216 |
+
|
217 |
+
function set_filtered_columns( $filtered_columns ){
|
218 |
+
$filtered_columns = ( is_array( $filtered_columns ) ) ? array_walk( $filtered_columns, 'sanitize_text_field' ) : explode( ',', sanitize_text_field( $filtered_columns ) );
|
219 |
+
|
220 |
+
if( empty( $filtered_columns[0] ) )
|
221 |
+
$filtered_columns = array();
|
222 |
+
|
223 |
+
$this->filtered_columns = $filtered_columns;
|
224 |
+
}
|
225 |
+
|
226 |
+
function get_filtered_columns(){
|
227 |
+
return $this->filtered_columns;
|
228 |
+
}
|
229 |
+
|
230 |
+
function set_orderby( $orderby ){
|
231 |
+
$this->orderby = $orderby;
|
232 |
+
}
|
233 |
+
|
234 |
+
function get_orderby(){
|
235 |
+
return $this->orderby;
|
236 |
+
}
|
237 |
+
|
238 |
+
function set_order( $order ){
|
239 |
+
$this->order = $order;
|
240 |
+
}
|
241 |
+
|
242 |
+
function get_order(){
|
243 |
+
return $this->order;
|
244 |
+
}
|
245 |
+
|
246 |
+
function get_total_rows(){
|
247 |
+
$total_rows = get_transient( 'acui_export_total_rows' );
|
248 |
+
|
249 |
+
if( empty( $total_rows ) ){
|
250 |
+
$this->total_rows = $this->calculate_total();
|
251 |
+
}
|
252 |
+
else{
|
253 |
+
$this->total_rows = $total_rows;
|
254 |
+
}
|
255 |
+
|
256 |
+
return $this->total_rows;
|
257 |
+
}
|
258 |
+
|
259 |
+
function get_total_steps(){
|
260 |
+
return floor( $this->get_total_rows() / $this->get_limit() ) + 1;
|
261 |
+
}
|
262 |
+
|
263 |
+
function set_time_limit( $limit = 0 ) {
|
264 |
+
if ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
|
265 |
+
@set_time_limit( $limit );
|
266 |
+
}
|
267 |
+
}
|
268 |
+
|
269 |
+
function send_headers() {
|
270 |
+
if ( function_exists( 'gc_enable' ) ) {
|
271 |
+
gc_enable();
|
272 |
+
}
|
273 |
+
if ( function_exists( 'apache_setenv' ) ) {
|
274 |
+
@apache_setenv( 'no-gzip', 1 );
|
275 |
+
}
|
276 |
+
@ini_set( 'zlib.output_compression', 'Off' );
|
277 |
+
@ini_set( 'output_buffering', 'Off' );
|
278 |
+
@ini_set( 'output_handler', '' );
|
279 |
+
ignore_user_abort( true );
|
280 |
+
$this->set_time_limit( 0 );
|
281 |
+
wc_nocache_headers();
|
282 |
+
header( 'Content-Type: text/csv; charset=utf-8' );
|
283 |
+
header( 'Content-Disposition: attachment; filename=' . $this->get_filename() );
|
284 |
+
header( 'Pragma: no-cache' );
|
285 |
+
header( 'Expires: 0' );
|
286 |
+
}
|
287 |
+
|
288 |
+
function set_filename( $filename ) {
|
289 |
+
$this->filename = sanitize_file_name( str_replace( '.csv', '', $filename ) . '.csv' );
|
290 |
+
}
|
291 |
+
|
292 |
+
function get_filename() {
|
293 |
+
return sanitize_file_name( $this->filename );
|
294 |
+
}
|
295 |
+
|
296 |
+
function send_content( $csv_data ) {
|
297 |
+
echo $csv_data;
|
298 |
+
}
|
299 |
+
|
300 |
+
protected function get_csv_data() {
|
301 |
+
return $this->export_rows();
|
302 |
+
}
|
303 |
+
|
304 |
+
protected function export_column_headers() {
|
305 |
+
$columns = $this->get_columns_to_export();
|
306 |
+
$export_row = array();
|
307 |
+
$buffer = fopen( 'php://output', 'w' );
|
308 |
+
ob_start();
|
309 |
+
|
310 |
+
foreach ( $columns as $column_name ) {
|
311 |
+
$export_row[] = $this->format_data( $column_name );
|
312 |
+
}
|
313 |
+
|
314 |
+
$this->fputcsv( $buffer, $export_row );
|
315 |
+
|
316 |
+
return ob_get_clean();
|
317 |
+
}
|
318 |
+
|
319 |
+
protected function get_data_to_export() {
|
320 |
+
return $this->row_data;
|
321 |
+
}
|
322 |
+
|
323 |
+
protected function export_rows() {
|
324 |
+
$data = $this->get_data_to_export();
|
325 |
+
$buffer = fopen( 'php://output', 'w' );
|
326 |
+
ob_start();
|
327 |
+
|
328 |
+
array_walk( $data, array( $this, 'export_row' ), $buffer );
|
329 |
+
|
330 |
+
return ob_get_clean();
|
331 |
+
}
|
332 |
+
|
333 |
+
protected function export_row( $row_data, $key, $buffer ) {
|
334 |
+
$this->fputcsv( $buffer, $row_data );
|
335 |
+
++ $this->exported_row_count;
|
336 |
+
}
|
337 |
+
|
338 |
+
function get_limit() {
|
339 |
+
return $this->limit;
|
340 |
+
}
|
341 |
+
|
342 |
+
function set_limit( $limit ) {
|
343 |
+
$this->limit = absint( $limit );
|
344 |
+
}
|
345 |
+
|
346 |
+
function escape_data( $data ) {
|
347 |
+
$active_content_triggers = array( '=', '+', '-', '@' );
|
348 |
+
|
349 |
+
if ( in_array( mb_substr( $data, 0, 1 ), $active_content_triggers, true ) ) {
|
350 |
+
$data = "'" . $data;
|
351 |
+
}
|
352 |
+
|
353 |
+
return $data;
|
354 |
+
}
|
355 |
+
|
356 |
+
function format_data( $data ) {
|
357 |
+
if ( is_bool( $data ) ) {
|
358 |
+
$data = $data ? 1 : 0;
|
359 |
+
}
|
360 |
+
|
361 |
+
$use_mb = function_exists( 'mb_convert_encoding' );
|
362 |
+
if ( $use_mb ) {
|
363 |
+
$encoding = mb_detect_encoding( $data, 'UTF-8, ISO-8859-1', true );
|
364 |
+
$data = 'UTF-8' === $encoding ? $data : utf8_encode( $data );
|
365 |
+
}
|
366 |
+
|
367 |
+
return $this->escape_data( $data );
|
368 |
+
}
|
369 |
+
|
370 |
+
protected function implode_values( $values ) {
|
371 |
+
$values_to_implode = array();
|
372 |
+
|
373 |
+
foreach ( $values as $value ) {
|
374 |
+
$value = (string) is_scalar( $value ) ? $value : '';
|
375 |
+
$values_to_implode[] = str_replace( ',', '\\,', $value );
|
376 |
+
}
|
377 |
+
|
378 |
+
return implode( ', ', $values_to_implode );
|
379 |
+
}
|
380 |
+
|
381 |
+
protected function fputcsv( $buffer, $export_row ) {
|
382 |
+
if ( version_compare( PHP_VERSION, '5.5.4', '<' ) ) {
|
383 |
+
ob_start();
|
384 |
+
$temp = fopen( 'php://output', 'w' );
|
385 |
+
fputcsv( $temp, $export_row, $this->get_delimiter(), '"' );
|
386 |
+
fclose( $temp );
|
387 |
+
$row = ob_get_clean();
|
388 |
+
$row = str_replace( '\\"', '\\""', $row );
|
389 |
+
fwrite( $buffer, $row );
|
390 |
+
} else {
|
391 |
+
fputcsv( $buffer, $export_row, $this->get_delimiter(), '"', "\0" );
|
392 |
+
}
|
393 |
+
}
|
394 |
+
|
395 |
+
protected function get_file_path() {
|
396 |
+
$upload_dir = wp_upload_dir();
|
397 |
+
return trailingslashit( $upload_dir['basedir'] ) . $this->get_filename();
|
398 |
+
}
|
399 |
+
|
400 |
+
protected function get_headers_row_file_path() {
|
401 |
+
return $this->get_file_path() . '.headers';
|
402 |
+
}
|
403 |
+
|
404 |
+
function get_headers_row_file() {
|
405 |
+
$file = chr( 239 ) . chr( 187 ) . chr( 191 ) . $this->export_column_headers();
|
406 |
+
|
407 |
+
if ( @file_exists( $this->get_headers_row_file_path() ) ){
|
408 |
+
$file = @file_get_contents( $this->get_headers_row_file_path() );
|
409 |
+
}
|
410 |
+
|
411 |
+
return $file;
|
412 |
+
}
|
413 |
+
|
414 |
+
function get_file() {
|
415 |
+
$file = '';
|
416 |
+
if ( @file_exists( $this->get_file_path() ) ){
|
417 |
+
$file = @file_get_contents( $this->get_file_path() );
|
418 |
+
} else {
|
419 |
+
@file_put_contents( $this->get_file_path(), '' );
|
420 |
+
@chmod( $this->get_file_path(), 0664 );
|
421 |
+
}
|
422 |
+
return $file;
|
423 |
+
}
|
424 |
+
|
425 |
+
function export() {
|
426 |
+
$this->send_headers();
|
427 |
+
$this->send_content( $this->get_headers_row_file() . $this->get_file() );
|
428 |
+
@unlink( $this->get_file_path() );
|
429 |
+
@unlink( $this->get_headers_row_file_path() );
|
430 |
+
die();
|
431 |
+
}
|
432 |
+
|
433 |
+
function generate_file() {
|
434 |
+
if( 1 === $this->get_page() ){
|
435 |
+
@unlink( $this->get_file_path() );
|
436 |
+
|
437 |
+
$this->get_file();
|
438 |
+
}
|
439 |
+
$this->prepare_data_to_export();
|
440 |
+
$this->write_csv_data( $this->get_csv_data() );
|
441 |
+
}
|
442 |
+
|
443 |
+
function calculate_total(){
|
444 |
+
$total_rows = count( $this->get_user_id_list( true ) );
|
445 |
+
set_transient( 'acui_export_total_rows', $total_rows, HOUR_IN_SECONDS );
|
446 |
+
|
447 |
+
return $total_rows;
|
448 |
+
}
|
449 |
+
|
450 |
+
protected function write_csv_data( $data ) {
|
451 |
+
if ( ! file_exists( $this->get_file_path() ) || ! is_writeable( $this->get_file_path() ) ) {
|
452 |
+
return false;
|
453 |
+
}
|
454 |
+
|
455 |
+
$fp = fopen( $this->get_file_path(), 'a+' );
|
456 |
+
|
457 |
+
if ( $fp ) {
|
458 |
+
fwrite( $fp, $data );
|
459 |
+
fclose( $fp );
|
460 |
+
}
|
461 |
+
|
462 |
+
if ( 100 <= $this->get_percent_complete() ) {
|
463 |
+
$header = chr( 239 ) . chr( 187 ) . chr( 191 ) . $this->export_column_headers();
|
464 |
+
|
465 |
+
@file_put_contents( $this->get_headers_row_file_path(), $header );
|
466 |
+
}
|
467 |
+
|
468 |
+
}
|
469 |
+
|
470 |
+
function get_page() {
|
471 |
+
return $this->page;
|
472 |
+
}
|
473 |
+
|
474 |
+
function set_page( $page ) {
|
475 |
+
$this->page = absint( $page );
|
476 |
+
}
|
477 |
+
|
478 |
+
function get_total_exported() {
|
479 |
+
return ( ( $this->get_page() - 1 ) * $this->get_limit() ) + $this->exported_row_count;
|
480 |
+
}
|
481 |
+
|
482 |
+
function get_percent_complete() {
|
483 |
+
return $this->get_total_rows() ? floor( ( $this->get_total_exported() / $this->get_total_rows() ) * 100 ) : 100;
|
484 |
+
}
|
485 |
+
|
486 |
+
function get_user_data(){
|
487 |
+
if( count( $this->get_filtered_columns() ) == 0 )
|
488 |
+
return $this->user_data;
|
489 |
+
|
490 |
+
$result = array();
|
491 |
+
foreach( $this->user_data as $column ){
|
492 |
+
if( in_array( $column, $this->get_filtered_columns() ) )
|
493 |
+
$result[] = $column;
|
494 |
+
}
|
495 |
+
|
496 |
+
return $result;
|
497 |
+
}
|
498 |
+
|
499 |
+
function get_user_id_list( $calculate_total = false ){
|
500 |
+
$args = array( 'fields' => array( 'ID' ), 'order' => $this->get_order() );
|
501 |
+
|
502 |
+
if( !$calculate_total ){
|
503 |
+
$args['number' ] = $this->get_limit();
|
504 |
+
$args['offset'] = ($this->get_page() - 1) * $this->get_limit();
|
505 |
+
}
|
506 |
+
|
507 |
+
if( !empty( $this->get_role() ) )
|
508 |
+
$args['role'] = $this->get_role();
|
509 |
+
|
510 |
+
$date_query = array();
|
511 |
+
|
512 |
+
if( !empty( $this->get_from() ) )
|
513 |
+
$date_query[] = array( 'after' => $this->get_from() );
|
514 |
+
|
515 |
+
if( !empty( $this->get_to() ) )
|
516 |
+
$date_query[] = array( 'before' => $this->get_to() );
|
517 |
+
|
518 |
+
if( !empty( $date_query ) ){
|
519 |
+
$date_query['inclusive'] = true;
|
520 |
+
$args['date_query'] = $date_query;
|
521 |
+
}
|
522 |
+
|
523 |
+
if( !empty( $this->get_orderby() ) ){
|
524 |
+
if( in_array( $this->get_orderby(), $this->accepted_order_by ) )
|
525 |
+
$args['orderby'] = $this->get_orderby();
|
526 |
+
else{
|
527 |
+
$args['orderby'] = "meta_value";
|
528 |
+
$args['meta_key'] = $this->get_orderby();
|
529 |
+
}
|
530 |
+
}
|
531 |
+
|
532 |
+
$users = get_users( $args );
|
533 |
+
|
534 |
+
if( $calculate_total )
|
535 |
+
return $users;
|
536 |
+
|
537 |
+
$list = array();
|
538 |
+
|
539 |
+
foreach ( $users as $user ) {
|
540 |
+
$list[] = $user->ID;
|
541 |
+
}
|
542 |
+
|
543 |
+
return $list;
|
544 |
+
}
|
545 |
+
|
546 |
+
function prepare_data_to_export() {
|
547 |
+
$users = $this->get_user_id_list();
|
548 |
+
$this->row_data = array();
|
549 |
+
|
550 |
+
foreach ( $users as $user ) {
|
551 |
+
$row = array();
|
552 |
+
$userdata = get_userdata( $user );
|
553 |
+
|
554 |
+
foreach ( $this->get_user_data( $this->get_filtered_columns() ) as $key ) {
|
555 |
+
$key = apply_filters( 'acui_export_get_key_user_data', $key );
|
556 |
+
$row[ $key ] = $this->prepare( $key, $userdata->data->{$key}, $this->get_datetime_format(), $user );
|
557 |
+
}
|
558 |
+
|
559 |
+
if( count( $this->get_filtered_columns() ) == 0 || in_array( 'role', $this->get_filtered_columns() ) )
|
560 |
+
$row[] = $this->get_role( $user );
|
561 |
+
|
562 |
+
foreach ( $this->get_user_meta_keys( $this->get_filtered_columns() ) as $key ) {
|
563 |
+
$row[ $key ] = $this->prepare( $key, get_user_meta( $user, $key, true ), $this->get_datetime_format(), $user );
|
564 |
+
}
|
565 |
+
|
566 |
+
if( count( $this->get_filtered_columns() ) == 0 || in_array( 'user_email', $this->get_filtered_columns() ) || in_array( 'user_login', $this->get_filtered_columns() ) )
|
567 |
+
$row = $this->maybe_fill_empty_data( $row, $user, $this->get_filtered_columns() );
|
568 |
+
|
569 |
+
$row = apply_filters( 'acui_export_data', $row, $user, $this->get_datetime_format(), $this->get_columns_to_export(), array( 'order_fields_alphabetically' => $this->get_order_fields_alphabetically(), 'double_encapsulate_serialized_values' => $this->get_double_encapsulate_serialized_values(), 'filtered_columns' => $this->get_filtered_columns() ));
|
570 |
+
|
571 |
+
$this->row_data[] = array_values( $row );
|
572 |
+
}
|
573 |
+
}
|
574 |
+
|
575 |
+
function prepare( $key, $value, $datetime_format, $user = 0 ){
|
576 |
+
$timestamp_keys = apply_filters( 'acui_export_timestamp_keys', array( 'wc_last_active' ) );
|
577 |
+
$non_date_keys = apply_filters( 'acui_export_non_date_keys', array() );
|
578 |
+
$original_value = $value;
|
579 |
+
|
580 |
+
if( $key == 'role' ){
|
581 |
+
return $this->get_role( $user );
|
582 |
+
}
|
583 |
+
if( is_array( $value ) || is_object( $value ) ){
|
584 |
+
return serialize( $value );
|
585 |
+
}
|
586 |
+
elseif( in_array( $key, $non_date_keys ) || empty( $datetime_format ) ){
|
587 |
+
return $this->clean_bad_characters_formulas( $value );
|
588 |
+
}
|
589 |
+
elseif( strtotime( $value ) ){ // dates in datetime format
|
590 |
+
return date( $datetime_format, strtotime( $value ) );
|
591 |
+
}
|
592 |
+
elseif( is_int( $value ) && ( ( $this->is_valid_timestamp( $value ) && strlen( $value ) > 4 ) || in_array( $key, $timestamp_keys) ) ){ // dates in timestamp format
|
593 |
+
return date( $datetime_format, $value );
|
594 |
+
}
|
595 |
+
else{
|
596 |
+
return apply_filters( 'acui_export_prepare', $this->clean_bad_characters_formulas( $value ), $original_value );
|
597 |
+
}
|
598 |
+
}
|
599 |
+
|
600 |
+
function clean_bad_characters_formulas( $value ){
|
601 |
+
if( strlen( $value ) == 0 )
|
602 |
+
return $value;
|
603 |
+
|
604 |
+
$bad_characters = array( '+', '-', '=', '@' );
|
605 |
+
$first_character = substr( $value, 0, 1 );
|
606 |
+
if( in_array( $first_character, $bad_characters ) )
|
607 |
+
$value = "\\" . $first_character . substr( $value, 1 );
|
608 |
+
|
609 |
+
return $value;
|
610 |
+
}
|
611 |
+
|
612 |
+
function is_valid_timestamp( $timestamp ){
|
613 |
+
return ( (string) (int) $timestamp === $timestamp ) && ( $timestamp <= PHP_INT_MAX ) && ( $timestamp >= ~PHP_INT_MAX );
|
614 |
+
}
|
615 |
+
|
616 |
+
function maybe_fill_empty_data( $row, $user_id, $filtered_columns ){
|
617 |
+
if( empty( $row['user_login'] ) || empty( $row['user_email'] ) ){
|
618 |
+
$user = new WP_User( $user_id );
|
619 |
+
|
620 |
+
if( $user->ID == 0 )
|
621 |
+
return $row;
|
622 |
+
|
623 |
+
if( count( $filtered_columns ) == 0 || in_array( 'user_login', $filtered_columns ) )
|
624 |
+
$row['user_login'] = $user->user_login;
|
625 |
+
|
626 |
+
if( count( $filtered_columns ) == 0 || in_array( 'user_email', $filtered_columns ) )
|
627 |
+
$row['user_email'] = $user->user_email;
|
628 |
+
}
|
629 |
+
|
630 |
+
return $row;
|
631 |
+
}
|
632 |
+
|
633 |
+
function get_user_meta_keys() {
|
634 |
+
global $wpdb;
|
635 |
+
$meta_keys = array();
|
636 |
+
|
637 |
+
$usermeta = get_transient( 'acui_export_user_meta_keys' );
|
638 |
+
|
639 |
+
if( empty( $usermeta ) ){
|
640 |
+
$usermeta = $wpdb->get_results( "SELECT distinct $wpdb->usermeta.meta_key FROM $wpdb->usermeta", ARRAY_A );
|
641 |
+
set_transient( 'acui_export_user_meta_keys', $usermeta, HOUR_IN_SECONDS );
|
642 |
+
}
|
643 |
+
|
644 |
+
foreach( $usermeta as $key => $value) {
|
645 |
+
if( $value["meta_key"] == 'role' )
|
646 |
+
continue;
|
647 |
+
|
648 |
+
if( count( $this->get_filtered_columns() ) == 0 || in_array( $value["meta_key"], $this->get_filtered_columns() ) )
|
649 |
+
$meta_keys[] = $value["meta_key"];
|
650 |
+
}
|
651 |
+
|
652 |
+
return apply_filters( 'acui_export_get_user_meta_keys', $meta_keys );
|
653 |
+
}
|
654 |
+
}
|
classes/export.php
CHANGED
@@ -17,21 +17,81 @@ class ACUI_Exporter{
|
|
17 |
$this->woocommerce_default_user_meta_keys = array( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone', 'billing_country', 'billing_address_1', 'billing_city', 'billing_state', 'billing_postcode', 'shipping_first_name', 'shipping_last_name', 'shipping_country', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode' );
|
18 |
$this->other_non_date_keys = array( 'shipping_phone' );
|
19 |
|
|
|
|
|
20 |
add_action( 'wp_ajax_acui_export_users_csv', array( $this, 'export_users_csv' ) );
|
21 |
-
add_filter( 'acui_export_get_key_user_data', array( $this, 'filter_key_user_id' ) );
|
22 |
-
add_filter( 'acui_export_non_date_keys', array( $this, 'get_non_date_keys' ), 1, 1 );
|
23 |
-
add_filter( 'acui_export_columns', array( $this, 'maybe_order_columns_alphabetacally' ), 10, 2 );
|
24 |
-
add_filter( 'acui_export_columns', array( $this, 'maybe_order_columns_filtered_columns_parameter' ), 11, 2 );
|
25 |
-
add_filter( 'acui_export_data', array( $this, 'maybe_double_encapsulate_serialized_values' ), 9 - 1, 5 );
|
26 |
-
add_filter( 'acui_export_data', array( $this, 'maybe_order_row_alphabetically' ), 10, 5 );
|
27 |
-
add_filter( 'acui_export_data', array( $this, 'maybe_order_row_filtered_columns_parameter' ), 11, 5 );
|
28 |
}
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
$roles = ACUI_Helper::get_editable_roles();
|
32 |
?>
|
33 |
<h3 id="acui_export_users_header"><?php _e( 'Export users', 'import-users-from-csv-with-meta' ); ?></h3>
|
34 |
-
<form id="
|
35 |
<table class="form-table">
|
36 |
<tbody>
|
37 |
<tr id="acui_role_wrapper" valign="top">
|
@@ -94,7 +154,12 @@ class ACUI_Exporter{
|
|
94 |
</tbody>
|
95 |
</table>
|
96 |
<input type="hidden" name="action" value="acui_export_users_csv"/>
|
97 |
-
<?php wp_nonce_field( 'codection-security', 'security' ); ?>
|
|
|
|
|
|
|
|
|
|
|
98 |
</form>
|
99 |
|
100 |
<script type="text/javascript">
|
@@ -119,331 +184,69 @@ class ACUI_Exporter{
|
|
119 |
<?php
|
120 |
}
|
121 |
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
function get_non_date_keys( $non_date_keys ){
|
127 |
-
return array_merge( $non_date_keys, $this->user_data, $this->woocommerce_default_user_meta_keys, $this->other_non_date_keys );
|
128 |
-
}
|
129 |
-
|
130 |
-
function maybe_order_columns_alphabetacally( $row, $args ){
|
131 |
-
if( !$args['order_fields_alphabetically'] )
|
132 |
-
return $row;
|
133 |
-
|
134 |
-
$first_two_columns = array_slice( $row, 0, 2 );
|
135 |
-
$to_order_columns = array_unique( array_slice( $row, 2 ) );
|
136 |
-
sort( $to_order_columns, SORT_LOCALE_STRING );
|
137 |
-
|
138 |
-
return array_merge( $first_two_columns, $to_order_columns );
|
139 |
-
}
|
140 |
-
|
141 |
-
function maybe_order_columns_filtered_columns_parameter( $row, $args ){
|
142 |
-
return ( !is_array( $args['filtered_columns'] ) || count( $args['filtered_columns'] ) == 0 ) ? $row : $args['filtered_columns'];
|
143 |
-
}
|
144 |
-
|
145 |
-
function maybe_order_row_alphabetically( $row, $user, $datetime_format, $columns, $args ){
|
146 |
-
if( !$args['order_fields_alphabetically'] )
|
147 |
-
return $row;
|
148 |
-
|
149 |
-
$row_sorted = array();
|
150 |
-
foreach( $columns as $field ){
|
151 |
-
$row_sorted[ $field ] = $row[ $field ];
|
152 |
-
}
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
function maybe_order_row_filtered_columns_parameter( $row, $user, $datetime_format, $columns, $args ){
|
158 |
-
if( !is_array( $args['filtered_columns'] ) || count( $args['filtered_columns'] ) == 0 )
|
159 |
-
return $row;
|
160 |
-
|
161 |
-
$row_sorted = array();
|
162 |
-
foreach( $args['filtered_columns'] as $field ){
|
163 |
-
$row_sorted[ $field ] = $row[ $field ];
|
164 |
-
}
|
165 |
-
|
166 |
-
return $row_sorted;
|
167 |
-
}
|
168 |
-
|
169 |
-
function maybe_double_encapsulate_serialized_values( $row, $user, $datetime_format, $columns, $args ){
|
170 |
-
if( !$args['double_encapsulate_serialized_values'] )
|
171 |
-
return $row;
|
172 |
-
|
173 |
-
foreach( $columns as $field ){
|
174 |
-
if( is_serialized( $row[ $field ] ) )
|
175 |
-
$row[ $field ] = '"' . $row[ $field ] . '"';
|
176 |
-
}
|
177 |
-
|
178 |
-
return $row;
|
179 |
-
}
|
180 |
-
|
181 |
-
static function clean_bad_characters_formulas( $value ){
|
182 |
-
if( strlen( $value ) == 0 )
|
183 |
-
return $value;
|
184 |
-
|
185 |
-
$bad_characters = array( '+', '-', '=', '@' );
|
186 |
-
$first_character = substr( $value, 0, 1 );
|
187 |
-
if( in_array( $first_character, $bad_characters ) )
|
188 |
-
$value = "\\" . $first_character . substr( $value, 1 );
|
189 |
-
|
190 |
-
return $value;
|
191 |
-
}
|
192 |
-
|
193 |
-
static function prepare( $key, $value, $datetime_format, $user = 0 ){
|
194 |
-
$timestamp_keys = apply_filters( 'acui_export_timestamp_keys', array( 'wc_last_active' ) );
|
195 |
-
$non_date_keys = apply_filters( 'acui_export_non_date_keys', array() );
|
196 |
-
$original_value = $value;
|
197 |
|
198 |
-
|
199 |
-
return self::get_role( $user );
|
200 |
-
}
|
201 |
-
if( is_array( $value ) || is_object( $value ) ){
|
202 |
-
return serialize( $value );
|
203 |
-
}
|
204 |
-
elseif( in_array( $key, $non_date_keys ) || empty( $datetime_format ) ){
|
205 |
-
return self::clean_bad_characters_formulas( $value );
|
206 |
-
}
|
207 |
-
elseif( strtotime( $value ) ){ // dates in datetime format
|
208 |
-
return date( $datetime_format, strtotime( $value ) );
|
209 |
}
|
210 |
-
elseif( is_int( $value ) && ( ( self::is_valid_timestamp( $value ) && strlen( $value ) > 4 ) || in_array( $key, $timestamp_keys) ) ){ // dates in timestamp format
|
211 |
-
return date( $datetime_format, $value );
|
212 |
-
}
|
213 |
-
else{
|
214 |
-
return apply_filters( 'acui_export_prepare', self::clean_bad_characters_formulas( $value ), $original_value );
|
215 |
-
}
|
216 |
-
}
|
217 |
-
|
218 |
-
static function get_role( $user_id ){
|
219 |
-
$user = get_user_by( 'id', $user_id );
|
220 |
-
return implode( ',', $user->roles );
|
221 |
}
|
222 |
|
223 |
-
function
|
224 |
-
|
225 |
-
|
226 |
-
if( empty( $filtered_columns[0] ) )
|
227 |
-
$filtered_columns = array();
|
228 |
-
|
229 |
-
return $filtered_columns;
|
230 |
-
}
|
231 |
-
|
232 |
-
function export_users_csv(){
|
233 |
-
check_ajax_referer( 'codection-security', 'security' );
|
234 |
|
235 |
if( !current_user_can( apply_filters( 'acui_capability', 'create_users' ) ) )
|
236 |
wp_die( __( 'Only users who are able to create users can export them.', 'import-users-from-csv-with-meta' ) );
|
237 |
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
$
|
246 |
-
$
|
247 |
-
$
|
248 |
-
$
|
249 |
-
$
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
case 'COLON':
|
257 |
-
$delimiter = ":";
|
258 |
-
break;
|
259 |
-
|
260 |
-
case 'SEMICOLON':
|
261 |
-
$delimiter = ";";
|
262 |
-
break;
|
263 |
-
|
264 |
-
case 'TAB':
|
265 |
-
$delimiter = "\t";
|
266 |
-
break;
|
267 |
-
|
268 |
-
default:
|
269 |
-
$delimiter = ",";
|
270 |
-
break;
|
271 |
-
}
|
272 |
-
|
273 |
-
$data = array();
|
274 |
-
$row = array();
|
275 |
-
|
276 |
-
// header
|
277 |
-
foreach ( $this->get_user_data( $filtered_columns ) as $key ) {
|
278 |
-
$row[] = $key;
|
279 |
-
}
|
280 |
-
|
281 |
-
if( count( $filtered_columns ) == 0 || in_array( 'role', $filtered_columns ) )
|
282 |
-
$row[] = "role";
|
283 |
-
|
284 |
-
foreach ( $this->get_user_meta_keys( $filtered_columns ) as $key ) {
|
285 |
-
$row[] = $key;
|
286 |
-
}
|
287 |
-
|
288 |
-
$row = apply_filters( 'acui_export_columns', $row, array( 'order_fields_alphabetically' => $order_fields_alphabetically, 'double_encapsulate_serialized_values' => $double_encapsulate_serialized_values, 'filtered_columns' => $filtered_columns ) );
|
289 |
-
$from = apply_filters( 'acui_export_user_registered_from_date', $from );
|
290 |
-
$to = apply_filters( 'acui_export_user_registered_to_date', $to );
|
291 |
-
|
292 |
-
$columns = $row;
|
293 |
-
$data[] = $row;
|
294 |
-
$row = array();
|
295 |
-
|
296 |
-
// data
|
297 |
-
$users = $this->get_user_id_list( $role, $from, $to, $orderby, $order );
|
298 |
-
foreach ( $users as $user ) {
|
299 |
-
$userdata = get_userdata( $user );
|
300 |
-
|
301 |
-
foreach ( $this->get_user_data( $filtered_columns ) as $key ) {
|
302 |
-
$key = apply_filters( 'acui_export_get_key_user_data', $key );
|
303 |
-
$row[ $key ] = self::prepare( $key, $userdata->data->{$key}, $datetime_format, $user );
|
304 |
-
}
|
305 |
-
|
306 |
-
if( count( $filtered_columns ) == 0 || in_array( 'role', $filtered_columns ) )
|
307 |
-
$row[] = $this->get_role( $user );
|
308 |
-
|
309 |
-
foreach ( $this->get_user_meta_keys( $filtered_columns ) as $key ) {
|
310 |
-
$row[ $key ] = self::prepare( $key, get_user_meta( $user, $key, true ), $datetime_format, $user );
|
311 |
-
}
|
312 |
-
|
313 |
-
if( count( $filtered_columns ) == 0 || in_array( 'user_email', $filtered_columns ) || in_array( 'user_login', $filtered_columns ) )
|
314 |
-
$row = $this->maybe_fill_empty_data( $row, $user, $filtered_columns );
|
315 |
-
|
316 |
-
$row = apply_filters( 'acui_export_data', $row, $user, $datetime_format, $columns, array( 'order_fields_alphabetically' => $order_fields_alphabetically, 'double_encapsulate_serialized_values' => $double_encapsulate_serialized_values, 'filtered_columns' => $filtered_columns ));
|
317 |
-
$data[] = array_values( $row );
|
318 |
-
$row = array();
|
319 |
-
}
|
320 |
-
|
321 |
-
// export to csv
|
322 |
-
$file = fopen( $this->path_csv, "w" );
|
323 |
-
|
324 |
-
foreach ( $data as $line ) {
|
325 |
-
fputcsv( $file, $line, $delimiter );
|
326 |
-
}
|
327 |
-
|
328 |
-
fclose( $file );
|
329 |
-
|
330 |
-
$fsize = filesize( $this->path_csv ) + 3;
|
331 |
-
$path_parts = pathinfo( $this->path_csv );
|
332 |
-
header( "Content-type: text/csv;charset=utf-8" );
|
333 |
-
header( "Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"" );
|
334 |
-
header( "Content-length: $fsize" );
|
335 |
-
header( "Cache-control: privfilefleate" );
|
336 |
-
header( "Content-Description: File Transfer" );
|
337 |
-
header( "Content-Transfer-Encoding: binary" );
|
338 |
-
header( "Expires: 0" );
|
339 |
-
header( "Cache-Control: must-revalidate" );
|
340 |
-
header( "Pragma: public" );
|
341 |
-
|
342 |
-
ob_clean();
|
343 |
-
flush();
|
344 |
-
|
345 |
-
echo "\xEF\xBB\xBF";
|
346 |
-
readfile( $this->path_csv );
|
347 |
-
|
348 |
-
unlink( $this->path_csv );
|
349 |
-
|
350 |
-
wp_die();
|
351 |
-
}
|
352 |
-
|
353 |
-
function get_user_data( $filtered_columns ){
|
354 |
-
if( count( $filtered_columns ) == 0 )
|
355 |
-
return $this->user_data;
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
}
|
364 |
-
|
365 |
-
return $result;
|
366 |
}
|
367 |
-
|
368 |
-
function get_user_meta_keys( $filtered_columns ) {
|
369 |
-
global $wpdb;
|
370 |
-
$meta_keys = array();
|
371 |
-
|
372 |
-
$select = "SELECT distinct $wpdb->usermeta.meta_key FROM $wpdb->usermeta";
|
373 |
-
$usermeta = $wpdb->get_results( $select, ARRAY_A );
|
374 |
-
|
375 |
-
foreach ($usermeta as $key => $value) {
|
376 |
-
if( $value["meta_key"] == 'role' )
|
377 |
-
continue;
|
378 |
-
|
379 |
-
if( count( $filtered_columns ) == 0 || in_array( $value["meta_key"], $filtered_columns ) )
|
380 |
-
$meta_keys[] = $value["meta_key"];
|
381 |
-
}
|
382 |
-
|
383 |
-
return apply_filters( 'acui_export_get_user_meta_keys', $meta_keys );
|
384 |
-
}
|
385 |
-
|
386 |
-
function get_user_id_list( $role, $from, $to, $orderby = '', $order = 'ASC' ){
|
387 |
-
$args = array( 'fields' => array( 'ID' ), 'order' => $order );
|
388 |
-
|
389 |
-
if( !empty( $role ) )
|
390 |
-
$args['role'] = $role;
|
391 |
-
|
392 |
-
$date_query = array();
|
393 |
-
|
394 |
-
if( !empty( $from ) )
|
395 |
-
$date_query[] = array( 'after' => $from );
|
396 |
-
|
397 |
-
if( !empty( $to ) )
|
398 |
-
$date_query[] = array( 'before' => $to );
|
399 |
-
|
400 |
-
if( !empty( $date_query ) ){
|
401 |
-
$date_query['inclusive'] = true;
|
402 |
-
$args['date_query'] = $date_query;
|
403 |
-
}
|
404 |
-
|
405 |
-
if( !empty( $orderby ) ){
|
406 |
-
if( in_array( $orderby, $this->accepted_order_by ) )
|
407 |
-
$args['orderby'] = $orderby;
|
408 |
-
else{
|
409 |
-
$args['orderby'] = "meta_value";
|
410 |
-
$args['meta_key'] = $orderby;
|
411 |
-
}
|
412 |
-
|
413 |
-
if( !empty( $order ) )
|
414 |
-
$args['order'] = $order;
|
415 |
-
}
|
416 |
-
|
417 |
-
$users = get_users( $args );
|
418 |
-
$list = array();
|
419 |
-
|
420 |
-
foreach ( $users as $user ) {
|
421 |
-
$list[] = $user->ID;
|
422 |
-
}
|
423 |
-
|
424 |
-
return $list;
|
425 |
-
}
|
426 |
-
|
427 |
-
function filter_key_user_id( $key ){
|
428 |
-
return ( $key == 'source_user_id' ) ? 'ID' : $key;
|
429 |
-
}
|
430 |
-
|
431 |
-
function maybe_fill_empty_data( $row, $user_id, $filtered_columns ){
|
432 |
-
if( empty( $row['user_login'] ) || empty( $row['user_email'] ) ){
|
433 |
-
$user = new WP_User( $user_id );
|
434 |
-
|
435 |
-
if( $user->ID == 0 )
|
436 |
-
return $row;
|
437 |
-
|
438 |
-
if( count( $filtered_columns ) == 0 || in_array( 'user_login', $filtered_columns ) )
|
439 |
-
$row['user_login'] = $user->user_login;
|
440 |
-
|
441 |
-
if( count( $filtered_columns ) == 0 || in_array( 'user_email', $filtered_columns ) )
|
442 |
-
$row['user_email'] = $user->user_email;
|
443 |
-
}
|
444 |
-
|
445 |
-
return $row;
|
446 |
-
}
|
447 |
}
|
448 |
|
449 |
$acui_exporter = new ACUI_Exporter();
|
17 |
$this->woocommerce_default_user_meta_keys = array( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone', 'billing_country', 'billing_address_1', 'billing_city', 'billing_state', 'billing_postcode', 'shipping_first_name', 'shipping_last_name', 'shipping_country', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode' );
|
18 |
$this->other_non_date_keys = array( 'shipping_phone' );
|
19 |
|
20 |
+
add_action( 'init', array( $this, 'download_export_file' ) );
|
21 |
+
add_action( 'admin_init', array( $this, 'download_export_file' ) );
|
22 |
add_action( 'wp_ajax_acui_export_users_csv', array( $this, 'export_users_csv' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
+
static function enqueue(){
|
26 |
+
wp_enqueue_script( 'acui_export_js', plugins_url( 'assets/export.js', dirname( __FILE__ ) ), false, time(), true );
|
27 |
+
wp_localize_script( 'acui_export_js', 'acui_export_js_object', array(
|
28 |
+
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
29 |
+
'starting_process' => __( 'Starting process', 'import-users-from-csv-with-meta' ),
|
30 |
+
'step' => __( 'Step', 'import-users-from-csv-with-meta' ),
|
31 |
+
'of_approximately' => __( 'of approximately', 'import-users-from-csv-with-meta' ),
|
32 |
+
'steps' => __( 'steps', 'import-users-from-csv-with-meta' ),
|
33 |
+
) );
|
34 |
+
}
|
35 |
+
|
36 |
+
static function styles(){
|
37 |
+
?>
|
38 |
+
<style>
|
39 |
+
#acui_exporter .user-exporter-progress-wrapper{
|
40 |
+
padding: 5px;
|
41 |
+
background-color: white;
|
42 |
+
width: 80%;
|
43 |
+
margin: 0 auto;
|
44 |
+
text-align: center;
|
45 |
+
}
|
46 |
+
|
47 |
+
#acui_exporter .user-exporter-progress{
|
48 |
+
width: 100%;
|
49 |
+
height: 42px;
|
50 |
+
border: 0;
|
51 |
+
border-radius: 9px;
|
52 |
+
}
|
53 |
+
.user-exporter-progress::-webkit-progress-bar {
|
54 |
+
background-color: #f3f3f3;
|
55 |
+
border-radius: 9px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.user-exporter-progress::-webkit-progress-value {
|
59 |
+
background: #2271b1;
|
60 |
+
border-radius: 9px;
|
61 |
+
}
|
62 |
+
|
63 |
+
.user-exporter-progress::-moz-progress-bar {
|
64 |
+
background: #2271b1;
|
65 |
+
border-radius: 9px;
|
66 |
+
}
|
67 |
+
|
68 |
+
.user-exporter-progress .progress-value {
|
69 |
+
padding: 0px 5px;
|
70 |
+
line-height: 20px;
|
71 |
+
margin-left: 5px;
|
72 |
+
font-size: .8em;
|
73 |
+
color: #555;
|
74 |
+
height: 18px;
|
75 |
+
float: right;
|
76 |
+
}
|
77 |
+
|
78 |
+
#acui_exporter.user-exporter__exporting table,
|
79 |
+
#acui_exporter .user-exporter-progress-wrapper{
|
80 |
+
display: none;
|
81 |
+
}
|
82 |
+
|
83 |
+
#acui_exporter.user-exporter__exporting .user-exporter-progress-wrapper{
|
84 |
+
display: block;
|
85 |
+
}
|
86 |
+
</style>
|
87 |
+
<?php
|
88 |
+
}
|
89 |
+
|
90 |
+
static function admin_gui(){
|
91 |
$roles = ACUI_Helper::get_editable_roles();
|
92 |
?>
|
93 |
<h3 id="acui_export_users_header"><?php _e( 'Export users', 'import-users-from-csv-with-meta' ); ?></h3>
|
94 |
+
<form id="acui_exporter">
|
95 |
<table class="form-table">
|
96 |
<tbody>
|
97 |
<tr id="acui_role_wrapper" valign="top">
|
154 |
</tbody>
|
155 |
</table>
|
156 |
<input type="hidden" name="action" value="acui_export_users_csv"/>
|
157 |
+
<?php wp_nonce_field( 'codection-security', 'security' ); ?>
|
158 |
+
|
159 |
+
<div class="user-exporter-progress-wrapper">
|
160 |
+
<progress class="user-exporter-progress" value="0" max="100"></progress>
|
161 |
+
<span class="user-exporter-progress-value">0%</span>
|
162 |
+
</div>
|
163 |
</form>
|
164 |
|
165 |
<script type="text/javascript">
|
184 |
<?php
|
185 |
}
|
186 |
|
187 |
+
function download_export_file() {
|
188 |
+
if ( current_user_can( apply_filters( 'acui_capability', 'create_users' ) ) && isset( $_GET['action'], $_GET['nonce'] ) && wp_verify_nonce( wp_unslash( $_GET['nonce'] ), 'codection-security' ) && 'download_user_csv' === wp_unslash( $_GET['action'] ) ) {
|
189 |
+
$exporter = new ACUI_Batch_Exporter();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
+
if ( !empty( $_GET['filename'] ) ){
|
192 |
+
$exporter->set_filename( wp_unslash( $_GET['filename'] ) );
|
193 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
|
195 |
+
$exporter->export();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
+
function export_users_csv(){
|
200 |
+
check_ajax_referer( 'codection-security', 'security' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
|
202 |
if( !current_user_can( apply_filters( 'acui_capability', 'create_users' ) ) )
|
203 |
wp_die( __( 'Only users who are able to create users can export them.', 'import-users-from-csv-with-meta' ) );
|
204 |
|
205 |
+
|
206 |
+
$step = isset( $_POST['step'] ) ? absint( $_POST['step'] ) : 1;
|
207 |
+
|
208 |
+
$exporter = new ACUI_Batch_Exporter();
|
209 |
+
|
210 |
+
$exporter->set_page( $step );
|
211 |
+
$exporter->set_delimiter( sanitize_text_field( $_POST['delimiter'] ) );
|
212 |
+
$exporter->set_role( sanitize_text_field( $_POST['role'] ) );
|
213 |
+
$exporter->set_from( sanitize_text_field( $_POST['from'] ) );
|
214 |
+
$exporter->set_to( sanitize_text_field( $_POST['to'] ) );
|
215 |
+
$exporter->set_convert_timestamp( $_POST['convert_timestamp'] );
|
216 |
+
$exporter->set_datetime_format( sanitize_text_field( $_POST['datetime_format'] ) );
|
217 |
+
$exporter->set_order_fields_alphabetically( $_POST['order_fields_alphabetically'] );
|
218 |
+
$exporter->set_double_encapsulate_serialized_values( $_POST['double_encapsulate_serialized_values'] );
|
219 |
+
$exporter->set_filtered_columns( ( isset( $_POST['columns'] ) && !empty( $_POST['columns'] ) ) ? $_POST['columns'] : array() );
|
220 |
+
$exporter->set_orderby( ( isset( $_POST['orderby'] ) && !empty( $_POST['orderby'] ) ) ? sanitize_text_field( $_POST['orderby'] ) : '' );
|
221 |
+
$exporter->set_order( ( isset( $_POST['order'] ) && !empty( $_POST['order'] ) ) ? sanitize_text_field( $_POST['order'] ) : 'ASC' );
|
222 |
+
$exporter->load_columns();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
+
$exporter->generate_file();
|
225 |
+
|
226 |
+
if ( 100 <= $exporter->get_percent_complete() ) {
|
227 |
+
$query_args = array(
|
228 |
+
'nonce' => wp_create_nonce( 'codection-security' ),
|
229 |
+
'action' => 'download_user_csv',
|
230 |
+
'filename' => $exporter->get_filename()
|
231 |
+
);
|
232 |
+
|
233 |
+
wp_send_json_success(
|
234 |
+
array(
|
235 |
+
'step' => 'done',
|
236 |
+
'percentage' => 100,
|
237 |
+
'url' => add_query_arg( $query_args, admin_url( 'tools.php?page=acui&tab=export' ) ),
|
238 |
+
)
|
239 |
+
);
|
240 |
+
} else {
|
241 |
+
wp_send_json_success(
|
242 |
+
array(
|
243 |
+
'step' => ++$step,
|
244 |
+
'total_steps' => $exporter->get_total_steps(),
|
245 |
+
'percentage' => $exporter->get_percent_complete(),
|
246 |
+
)
|
247 |
+
);
|
248 |
}
|
|
|
|
|
249 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
}
|
251 |
|
252 |
$acui_exporter = new ACUI_Exporter();
|
classes/frontend.php
CHANGED
@@ -382,7 +382,7 @@ class ACUI_Frontend{
|
|
382 |
wp_mail( $send_mail_admin_adress_list_frontend, '[Import and export users and customers] Frontend import has been executed', $body_mail, array( 'Content-Type: text/html; charset=UTF-8' ) );
|
383 |
}
|
384 |
|
385 |
-
|
386 |
$atts = shortcode_atts( array( 'role' => '', 'delete-only-specified-role' => false ), $atts );
|
387 |
|
388 |
ob_start();
|
@@ -474,23 +474,32 @@ class ACUI_Frontend{
|
|
474 |
}
|
475 |
|
476 |
function shortcode_export( $atts ) {
|
477 |
-
|
478 |
|
479 |
ob_start();
|
480 |
|
481 |
if( !current_user_can( apply_filters( 'acui_capability', 'create_users' ) ) )
|
482 |
wp_die( __( 'Only users who are able to create users can export them.', 'import-users-from-csv-with-meta' ) );
|
483 |
-
?>
|
484 |
-
<form method="POST" action="<?php echo admin_url( 'admin-ajax.php' ); ?>" class="acui_frontend_form">
|
485 |
-
<input type="hidden" name="action" value="acui_export_users_csv"/>
|
486 |
|
487 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
<input type="hidden" name="<?php echo $key; ?>" value="<?php echo $value; ?>"/>
|
489 |
<?php endforeach; ?>
|
490 |
|
491 |
<input class="acui_frontend_submit" type="submit" value="<?php _e( 'Export', 'import-users-from-csv-with-meta' ); ?>"/>
|
492 |
|
493 |
<?php wp_nonce_field( 'codection-security', 'security' ); ?>
|
|
|
|
|
|
|
|
|
|
|
494 |
</form>
|
495 |
<?php
|
496 |
return ob_get_clean();
|
382 |
wp_mail( $send_mail_admin_adress_list_frontend, '[Import and export users and customers] Frontend import has been executed', $body_mail, array( 'Content-Type: text/html; charset=UTF-8' ) );
|
383 |
}
|
384 |
|
385 |
+
function shortcode_import( $atts ) {
|
386 |
$atts = shortcode_atts( array( 'role' => '', 'delete-only-specified-role' => false ), $atts );
|
387 |
|
388 |
ob_start();
|
474 |
}
|
475 |
|
476 |
function shortcode_export( $atts ) {
|
477 |
+
$atts = shortcode_atts( array( 'role' => '', 'from' => '', 'to' => '', 'delimiter' => '', 'order-alphabetically' => '', 'columns' => '', 'orderby' => '', 'order' => '' ), $atts );
|
478 |
|
479 |
ob_start();
|
480 |
|
481 |
if( !current_user_can( apply_filters( 'acui_capability', 'create_users' ) ) )
|
482 |
wp_die( __( 'Only users who are able to create users can export them.', 'import-users-from-csv-with-meta' ) );
|
|
|
|
|
|
|
483 |
|
484 |
+
ACUI_Exporter::enqueue();
|
485 |
+
ACUI_Exporter::styles();
|
486 |
+
?>
|
487 |
+
|
488 |
+
<form method="POST" class="acui_frontend_form" id="acui_exporter">
|
489 |
+
<input type="hidden" name="acui_frontend_export" value="1"/>
|
490 |
+
|
491 |
+
<?php foreach( $atts as $key => $value ): ?>
|
492 |
<input type="hidden" name="<?php echo $key; ?>" value="<?php echo $value; ?>"/>
|
493 |
<?php endforeach; ?>
|
494 |
|
495 |
<input class="acui_frontend_submit" type="submit" value="<?php _e( 'Export', 'import-users-from-csv-with-meta' ); ?>"/>
|
496 |
|
497 |
<?php wp_nonce_field( 'codection-security', 'security' ); ?>
|
498 |
+
|
499 |
+
<div class="user-exporter-progress-wrapper">
|
500 |
+
<progress class="user-exporter-progress" value="0" max="100"></progress>
|
501 |
+
<span class="user-exporter-progress-value">0%</span>
|
502 |
+
</div>
|
503 |
</form>
|
504 |
<?php
|
505 |
return ob_get_clean();
|
classes/settings.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
class ACUI_Settings{
|
5 |
+
var $settings;
|
6 |
+
|
7 |
+
function __construct(){
|
8 |
+
$settings = array(
|
9 |
+
'common' => array(
|
10 |
+
'default_role',
|
11 |
+
|
12 |
+
)
|
13 |
+
);
|
14 |
+
}
|
15 |
+
}
|
import-users-from-csv-with-meta.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Import and export users and customers
|
4 |
Plugin URI: https://www.codection.com
|
5 |
Description: Using this plugin you will be able to import and export users or customers choosing many options and interacting with lots of other plugins
|
6 |
-
Version: 1.
|
7 |
Author: codection
|
8 |
Author URI: https://codection.com
|
9 |
License: GPL2
|
@@ -91,6 +91,10 @@ class ImportExportUsersCustomers{
|
|
91 |
wp_enqueue_style( 'datatable', '//cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' );
|
92 |
wp_enqueue_script( 'datatable', '//cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js' );
|
93 |
//wp_enqueue_script( 'datatable-select', '//cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js' );
|
|
|
|
|
|
|
|
|
94 |
}
|
95 |
|
96 |
function action_links( $links, $file ) {
|
3 |
Plugin Name: Import and export users and customers
|
4 |
Plugin URI: https://www.codection.com
|
5 |
Description: Using this plugin you will be able to import and export users or customers choosing many options and interacting with lots of other plugins
|
6 |
+
Version: 1.18
|
7 |
Author: codection
|
8 |
Author URI: https://codection.com
|
9 |
License: GPL2
|
91 |
wp_enqueue_style( 'datatable', '//cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css' );
|
92 |
wp_enqueue_script( 'datatable', '//cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js' );
|
93 |
//wp_enqueue_script( 'datatable-select', '//cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js' );
|
94 |
+
|
95 |
+
if( isset( $_GET['tab'] ) && $_GET['tab'] == 'export' ){
|
96 |
+
ACUI_Exporter::enqueue();
|
97 |
+
}
|
98 |
}
|
99 |
|
100 |
function action_links( $links, $file ) {
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://codection.com/go/donate-import-users-from-csv-with-meta/
|
|
4 |
Tags: csv, import, importer, meta data, meta, user, users, user meta, editor, profile, custom, fields, delimiter, update, insert
|
5 |
Requires at least: 3.4
|
6 |
Tested up to: 5.8
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -103,8 +103,12 @@ Plugin will automatically detect:
|
|
103 |
|
104 |
== Changelog ==
|
105 |
|
|
|
|
|
|
|
|
|
106 |
= 1.17.9 =
|
107 |
-
* Export now can be ordered using an attribute in the shortcode
|
108 |
|
109 |
= 1.17.8.4 =
|
110 |
* Bug fixed in WP User Manager addon
|
4 |
Tags: csv, import, importer, meta data, meta, user, users, user meta, editor, profile, custom, fields, delimiter, update, insert
|
5 |
Requires at least: 3.4
|
6 |
Tested up to: 5.8
|
7 |
+
Stable tag: 1.18
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
103 |
|
104 |
== Changelog ==
|
105 |
|
106 |
+
= 1.18 =
|
107 |
+
* Export in backend and frontend now works using step by step process using client calls to avoid gateway timeouts and other kind of timing limits in very long process
|
108 |
+
* Addon for WP User Manager improved to avoid redirection loop
|
109 |
+
|
110 |
= 1.17.9 =
|
111 |
+
* Export now can be ordered using an attribute in the shortcode
|
112 |
|
113 |
= 1.17.8.4 =
|
114 |
* Bug fixed in WP User Manager addon
|