Export User Data - Version 1.2.1

Version Description

  • Checked on WP 4.3.1
  • Moved text-domain to string in preperation for addition to translate.wordpress.org
  • Added Log() method to allow for debugging to WP Error Log
  • Added Greek translation - Thanks @Leonidas Mi
  • Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
Download this release

Release Info

Developer qlstudio
Plugin Icon wp plugin Export User Data
Version 1.2.1
Comparing to
See all releases

Code changes from version 1.2.0 to 1.2.1

export-user-data.php CHANGED
@@ -1,1979 +1,2059 @@
1
- <?php
2
-
3
- /*
4
- Plugin Name: Export User Data
5
- Plugin URI: http://qstudio.us/plugins/
6
- Description: Export User data, metadata and BuddyPress X-Profile data.
7
- Version: 1.2.0
8
- Author: Q Studio
9
- Author URI: http://qstudio.us
10
- License: GPL2
11
- Text Domain: export-user-data
12
- */
13
-
14
- // quick check :) ##
15
- defined( 'ABSPATH' ) OR exit;
16
-
17
- // Increase maximum execution time to prevent "Maximum execution time
18
- // exceeded" error
19
- ini_set('max_execution_time', 3600);
20
-
21
- /* Check for Class */
22
- if ( ! class_exists( 'Q_Export_User_Data' ) )
23
- {
24
-
25
- // plugin version
26
- define( 'Q_EXPORT_USER_DATA_VERSION', '1.2.0' ); // version ##
27
-
28
- // instatiate class via hook, only if inside admin
29
- if ( is_admin() ) {
30
-
31
- // instatiate plugin via WP hook - not too early, not too late ##
32
- add_action( 'init', array ( 'Q_Export_User_Data', 'get_instance' ), 0 );
33
-
34
- }
35
-
36
-
37
- /**
38
- * Main plugin class
39
- *
40
- * @since 0.1
41
- **/
42
- class Q_Export_User_Data {
43
-
44
-
45
- // Refers to a single instance of this class. ##
46
- private static $instance = null;
47
-
48
- /* properties */
49
- public $text_domain = 'export-user-data'; // for translation ##
50
- private $q_eud_exports = ''; // export settings ##
51
- private $usermeta_saved_fields = array();
52
- private $bp_fields_saved_fields = array();
53
- private $bp_fields_update_time_saved_fields = array();
54
- private $role = '';
55
- private $roles = '1';
56
- private $groups = '1';
57
- private $start_date = '';
58
- private $end_date = '';
59
- private $limit_offset = '';
60
- private $limit_total = '';
61
- private $format = '';
62
-
63
-
64
- /**
65
- * Creates or returns an instance of this class.
66
- *
67
- * @return Foo A single instance of this class.
68
- */
69
- public static function get_instance() {
70
-
71
- if ( null == self::$instance ) {
72
- self::$instance = new self;
73
- }
74
-
75
- return self::$instance;
76
-
77
- }
78
-
79
-
80
- /**
81
- * Class contructor
82
- *
83
- * @since 0.1
84
- **/
85
- private function __construct()
86
- {
87
-
88
- if ( is_admin() ) {
89
-
90
- add_action( 'init', array( $this, 'load_plugin_textdomain' ), 1 );
91
- add_action( 'init', array( $this, 'load_user_options' ), 2 );
92
- add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
93
- add_action( 'init', array( $this, 'generate_data' ), 3 );
94
- add_filter( 'q_eud_exclude_data', array( $this, 'exclude_data' ) );
95
- add_action( 'admin_enqueue_scripts', array( $this, 'add_css_and_js' ), 1 );
96
- add_action( 'admin_footer', array( $this, 'jquery' ), 100000 );
97
- add_action( 'admin_footer', array( $this, 'css' ), 100000 );
98
-
99
- }
100
-
101
- }
102
-
103
-
104
- /**
105
- * Load plugin text-domain
106
- *
107
- * @since 0.9.0
108
- * @return void
109
- **/
110
- public function load_plugin_textdomain()
111
- {
112
-
113
- load_plugin_textdomain( $this->text_domain, false, basename( dirname( __FILE__ ) ) . '/languages' );
114
-
115
- }
116
-
117
- /**
118
- * Add administration menus
119
- *
120
- * @since 0.1
121
- **/
122
- public function add_admin_pages()
123
- {
124
-
125
- add_users_page( __( 'Export User Data', $this->text_domain ), __( 'Export User Data', $this->text_domain ), 'list_users', $this->text_domain, array( $this, 'users_page' ) );
126
-
127
- }
128
-
129
-
130
- /**
131
- * style and interaction
132
- */
133
- public function add_css_and_js( $hook )
134
- {
135
-
136
- // load the scripts on only the plugin admin page ##
137
- if ( isset( $_GET['page'] ) && ( $_GET['page'] == $this->text_domain ) ) {
138
-
139
- wp_register_style( 'q_export_user_data', plugins_url( 'css/export-user-data.css' ,__FILE__ ));
140
- wp_enqueue_style( 'q_export_user_data' );
141
- wp_enqueue_script( 'q_eud_multi_select_js', plugins_url( 'js/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
142
-
143
- // add script ##
144
- wp_enqueue_script('jquery-ui-datepicker');
145
-
146
- // add style ##
147
- wp_enqueue_style( 'jquery-ui-datepicker' );
148
- wp_enqueue_style('jquery-ui-css', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
149
-
150
- }
151
-
152
- }
153
-
154
-
155
- /**
156
- * Return Byte count of $val
157
- *
158
- * @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
159
- * @since 0.9.6
160
- */
161
- public function return_bytes( $val )
162
- {
163
-
164
- $val = trim( $val );
165
- $last = strtolower($val[strlen($val)-1]);
166
- switch( $last ) {
167
-
168
- // The 'G' modifier is available since PHP 5.1.0
169
- case 'g':
170
-
171
- $val *= 1024;
172
-
173
- case 'm':
174
-
175
- $val *= 1024;
176
-
177
- case 'k':
178
-
179
- $val *= 1024;
180
-
181
- }
182
-
183
- return $val;
184
- }
185
-
186
-
187
- /**
188
- * clean that stuff up
189
- */
190
- public function sanitize( $value )
191
- {
192
-
193
- $value = str_replace("\r", '', $value);
194
- $value = str_replace("\n", '', $value);
195
- $value = str_replace("\t", '', $value);
196
- return $value;
197
-
198
- }
199
-
200
-
201
- /**
202
- * Load up saved exports for this user
203
- *
204
- * @since 0.9.6
205
- * @return Array of saved exports
206
- */
207
- public function load_user_options()
208
- {
209
-
210
-
211
- $this->q_eud_exports = get_user_meta( get_current_user_id(), 'q_eud_exports' ) ? get_user_meta( get_current_user_id(), 'q_eud_exports', true ) : array() ;
212
- #var_dump( $this->q_eud_exports );
213
-
214
- }
215
-
216
-
217
- /**
218
- * Get list of saved exports for this user
219
- *
220
- * @since 0.9.4
221
- * @return Array of saved exports
222
- */
223
- public function get_user_options()
224
- {
225
-
226
- // get the stored options - filter empty array items ##
227
- $q_eud_exports = array_filter( $this->q_eud_exports );
228
-
229
- // quick check if the array is empty ##
230
- if ( empty ( $q_eud_exports ) ) {
231
-
232
- return false;
233
-
234
- }
235
-
236
- // test the array of saved exports ##
237
- #$this->pr( $q_eud_exports );
238
-
239
- // start with an empty array ##
240
- $exports = array();
241
-
242
- // loop over each saved export and grab each key ##
243
- foreach ( $q_eud_exports as $key => $value ) {
244
-
245
- $exports[] = $key;
246
-
247
- }
248
-
249
- // kick back array ##
250
- return( $exports );
251
-
252
- }
253
-
254
-
255
- /**
256
- * Check for and load stored user options
257
- *
258
- * @since 0.9.3
259
- * @return void
260
- */
261
- public function get_user_options_by_export( $export = null )
262
- {
263
-
264
- // sanity check ##
265
- if ( is_null ( $export ) ) { return false; }
266
-
267
- if ( isset( $this->q_eud_exports[$export] ) ) {
268
-
269
- $this->usermeta_saved_fields = $this->q_eud_exports[$export]['usermeta_saved_fields'];
270
- $this->bp_fields_saved_fields = $this->q_eud_exports[$export]['bp_fields_saved_fields'];
271
- $this->bp_fields_update_time_saved_fields = $this->q_eud_exports[$export]['bp_fields_update_time_saved_fields'];
272
- $this->role = $this->q_eud_exports[$export]['role'];
273
- $this->roles = $this->q_eud_exports[$export]['roles'];
274
- $this->groups = $this->q_eud_exports[$export]['groups'];
275
- $this->start_date = $this->q_eud_exports[$export]['start_date'];
276
- $this->end_date = $this->q_eud_exports[$export]['end_date'];
277
- $this->limit_offset = $this->q_eud_exports[$export]['limit_offset'];
278
- $this->limit_total = $this->q_eud_exports[$export]['limit_total'];
279
- $this->format = $this->q_eud_exports[$export]['format'];
280
-
281
- } else {
282
-
283
- $this->usermeta_saved_fields = array();
284
- $this->bp_fields_saved_fields = array();
285
- $this->bp_fields_update_time_saved_fields = array();
286
- $this->role = '';
287
- $this->roles = '1';
288
- $this->groups = '1';
289
- $this->start_date = '';
290
- $this->end_date = '';
291
- $this->limit_offset = '';
292
- $this->limit_total = '';
293
- $this->format = '';
294
-
295
- }
296
-
297
- }
298
-
299
-
300
- /**
301
- * method to store user options
302
- *
303
- * @param string $save_export Export Key name
304
- * @param array $save_options Array of export options to save
305
- * @since 0.9.3
306
- * @return void
307
- */
308
- public function set_user_options( $key = null, $options = null )
309
- {
310
-
311
- // sanity check ##
312
- if ( is_null ( $key ) || is_null ( $options ) ) {
313
-
314
- #$this->pr( 'missing save values' );
315
- return false;
316
-
317
- }
318
-
319
- #$this->pr( $key );
320
- #$this->pr( $options );
321
-
322
- // for now, I'm simply allowing keys to be resaved - but this is not so logical ##
323
- if ( array_key_exists( $key, $this->q_eud_exports ) ) {
324
-
325
- #$this->pr( 'key exists, skipping save' );
326
- #return false;
327
-
328
- }
329
-
330
- if ( isset( $options ) && is_array( $options ) ) {
331
-
332
- // update_option sanitizes the option name but not the option value ##
333
- foreach ( $options as $field_name => $field_value ) {
334
-
335
- // so do that here. ##
336
- if ( is_array( $field_value ) ) {
337
-
338
- foreach ( $field_value as $field_array_key => $field_array_value ) {
339
-
340
- $options[$field_name][$field_array_key] = sanitize_text_field( $field_array_value );
341
-
342
- }
343
-
344
- } else {
345
-
346
- $options[$field_name] = sanitize_text_field( $field_value );
347
-
348
- }
349
-
350
- }
351
-
352
- // assign the sanitized array of values to the class property $q_eud_exports as a new array with key $key ##
353
- $this->q_eud_exports[$key] = $options;
354
-
355
- // update stored user_meta values, if previous key found ##
356
- if ( get_user_meta( get_current_user_id(), 'q_eud_exports' ) !== false ) {
357
-
358
- #update_option( 'q_eud_exports', $this->q_eud_exports );
359
- update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
360
-
361
- // create new user meta key ##
362
- } else {
363
-
364
- #add_option( 'q_eud_exports', $this->q_eud_exports, $deprecated, $autoload );
365
- add_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
366
-
367
- }
368
-
369
- }
370
-
371
- }
372
-
373
-
374
- /**
375
- * method to delete user options
376
- *
377
- * @param $key String Key name to drop from property
378
- * @since 0.9.3
379
- * @return void
380
- */
381
- public function delete_user_options( $key = null )
382
- {
383
-
384
- // sanity check ##
385
- if ( is_null ( $key ) || ! array_key_exists( $key, $this->q_eud_exports ) ) { return false; }
386
-
387
- // clean it up ##
388
- $key = sanitize_text_field( $key );
389
-
390
- // check it out ##
391
- #$this->pr( $key );
392
-
393
- // drop the array by it's key name from the class property ##
394
- unset( $this->q_eud_exports[$key] );
395
-
396
- // update the saved data ##
397
- update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
398
-
399
- }
400
-
401
-
402
- /**
403
- * Copy of BP_XProfile_ProfileData::get_all_for_user() from BP version 2.0?
404
- * Get all of the profile information for a specific user.
405
- *
406
- * @param $user_id Integer ID of specific user
407
- * @since 0.9.6
408
- * @return Array User profile fields
409
- */
410
- private static function get_all_for_user( $user_id = null ) {
411
-
412
- // sanity check ##
413
- if ( is_null( $user_id ) ) { return false; }
414
-
415
- global $wpdb, $bp;
416
-
417
- $results = $wpdb->get_results(
418
- $wpdb->prepare(
419
- "
420
- SELECT g.id as field_group_id, g.name as field_group_name, f.id as field_id, f.name as field_name, f.type as field_type, d.value as field_data, u.user_login, u.user_nicename, u.user_email
421
- FROM {$bp->profile->table_name_groups} g
422
- LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id
423
- INNER JOIN {$bp->profile->table_name_data} d ON f.id = d.field_id LEFT JOIN {$wpdb->users} u ON d.user_id = u.ID
424
- WHERE d.user_id = %d AND d.value != ''
425
- "
426
- , $user_id
427
- )
428
- );
429
-
430
- $profile_data = array();
431
-
432
- if ( ! empty( $results ) ) {
433
-
434
- $profile_data['user_login'] = $results[0]->user_login;
435
- $profile_data['user_nicename'] = $results[0]->user_nicename;
436
- $profile_data['user_email'] = $results[0]->user_email;
437
-
438
- foreach( (array) $results as $field ) {
439
-
440
- $profile_data[$field->field_name] = array(
441
- 'field_group_id' => $field->field_group_id,
442
- 'field_group_name' => $field->field_group_name,
443
- 'field_id' => $field->field_id,
444
- 'field_type' => $field->field_type,
445
- 'field_data' => $field->field_data
446
- );
447
-
448
- }
449
-
450
- }
451
-
452
- return $profile_data;
453
-
454
- }
455
-
456
-
457
- /**
458
- * Process content of CSV file
459
- *
460
- * @since 0.1
461
- **/
462
- public function generate_data()
463
- {
464
-
465
- #self::pr( 'a:5:{i:0;s:7:"acf_676";i:1;s:15:"wordpress-https";i:2;s:16:"gp-theme-options";i:3;s:10:"postcustom";i:4;s:16:"commentstatusdiv";}' );
466
- #echo self::recursive_implode( 'a:5:{i:0;s:7:"acf_676";i:1;s:15:"wordpress-https";i:2;s:16:"gp-theme-options";i:3;s:10:"postcustom";i:4;s:16:"commentstatusdiv";}' );
467
-
468
- #self::pr( '58' );
469
- #echo self::recursive_implode( '58' );
470
-
471
- #self::pr( 'a:2:{i:0;s:3:"sub";i:1;a:1:{i:0;s:7:"acf_676";}}' );
472
- #echo self::recursive_implode( 'a:2:{i:0;s:3:"sub";i:1;a:1:{i:0;s:7:"acf_676";}}' );
473
-
474
- #wp_die();
475
-
476
- // Check if the user clicked on the Save, Load, or Delete Settings buttons ##
477
- if (
478
- ! isset( $_POST['_wpnonce-q-eud-export-user-page_export'] )
479
- || isset( $_POST['load_export'] )
480
- || isset( $_POST['save_export'] )
481
- || isset( $_POST['delete_export'] ) )
482
- {
483
-
484
- return false;
485
-
486
- }
487
-
488
- // check admin referer ##
489
- check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' );
490
-
491
- // build argument array ##
492
- $args = array(
493
- 'fields' => 'all',
494
- 'role' => sanitize_text_field( $_POST['role'] )
495
- );
496
-
497
- // did they request a specific program ? ##
498
- if ( isset( $_POST['program'] ) && $_POST['program'] != '' ) {
499
-
500
- $args['meta_key'] = 'member_of_club';
501
- $args['meta_value'] = (int)$_POST['program'];
502
- $args['meta_compare'] = '=';
503
-
504
- }
505
-
506
- // is there a range limit in place for the export ? ##
507
- if ( isset( $_POST['limit_total'] ) && $_POST['limit_total'] != '' ) {
508
-
509
- // let's just make sure they are integer values ##
510
- $limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
511
- $limit_total = (int)$_POST['limit_total'];
512
-
513
- if ( is_int( $limit_offset ) && is_int( $limit_total ) ) {
514
-
515
- $args['offset'] = $limit_offset;
516
- $args['number'] = $limit_total; // number - Limit the total number of users returned ##
517
-
518
- // test it ##
519
- #wp_die( $this->pr( $args ) );
520
-
521
- }
522
-
523
- }
524
-
525
- // pre_user query ##
526
- add_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
527
- $users = get_users( $args );
528
- remove_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
529
-
530
- // test args ##
531
- #wp_die( $this->pr ( $users ) );
532
-
533
- // no users found, so chuck an error into the args array and exit the export ##
534
- if ( ! $users ) {
535
-
536
- wp_redirect( add_query_arg( 'error', 'empty', wp_get_referer() ) );
537
- exit;
538
-
539
- }
540
-
541
- // get sitename and clean it up ##
542
- $sitename = sanitize_key( get_bloginfo( 'name' ) );
543
- if ( ! empty( $sitename ) ) {
544
- $sitename .= '.';
545
- }
546
-
547
- // export method ? ##
548
- $export_method = 'excel'; // default to Excel export ##
549
- if ( isset( $_POST['format'] ) && $_POST['format'] != '' ) {
550
-
551
- $export_method = sanitize_text_field( $_POST['format'] );
552
-
553
- }
554
-
555
- // set export filename structure ##
556
- $filename = $sitename . 'users.' . date( 'Y-m-d-H-i-s' );
557
-
558
- switch ( $export_method ) {
559
-
560
- case ( 'csv' ):
561
-
562
- // to csv ##
563
- header( 'Content-Description: File Transfer' );
564
- header( 'Content-Disposition: attachment; filename='.$filename.'.csv' );
565
- header( 'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ), true );
566
-
567
- // set a csv check flag
568
- $is_csv = true;
569
-
570
- // nothing here
571
- $doc_begin = '';
572
-
573
- //preformat
574
- $pre = '';
575
-
576
- // how to seperate data ##
577
- $seperator = ','; // comma for csv ##
578
-
579
- // line break ##
580
- $breaker = "\n";
581
-
582
- // nothing here
583
- $doc_end = '';
584
-
585
- break;
586
-
587
- case ( 'excel' ):
588
-
589
- // to xls ##
590
- header( 'Content-Description: File Transfer' );
591
- header("Content-Type: application/vnd.ms-excel");
592
- header("Content-Disposition: attachment; filename=$filename.xls");
593
- header("Pragma: no-cache");
594
- header("Expires: 0");
595
-
596
- // set a csv check flag
597
- $is_csv = false;
598
-
599
- //grab the template file (for tidy formatting)
600
- include( 'xml-template.php' );
601
-
602
- // open xml
603
- $doc_begin = $xml_doc_begin;
604
-
605
- //preformat
606
- $pre = $xml_pre;
607
-
608
- // how to seperate data ##
609
- $seperator = $xml_seperator;
610
-
611
- // line break ##
612
- $breaker = $xml_breaker;
613
-
614
- // close xml
615
- $doc_end = $xml_doc_end;
616
-
617
- break;
618
-
619
- }
620
-
621
-
622
- // check for selected usermeta fields ##
623
- $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
624
- #$this->pr( $usermeta );
625
- $usermeta_fields = array();
626
-
627
- if ( $usermeta && is_array( $usermeta ) ) {
628
- foreach( $usermeta as $field ) {
629
- $usermeta_fields[] = sanitize_text_field ( $field );
630
- }
631
- }
632
-
633
- #$this->pr( $usermeta_fields );
634
- #exit;
635
-
636
- // check for selected x profile fields ##
637
- $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '';
638
- $bp_fields_passed = array();
639
- if ( $bp_fields && is_array( $bp_fields ) ) {
640
-
641
- foreach( $bp_fields as $field ) {
642
-
643
- // reverse tidy ##
644
- $field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
645
-
646
- // add to array ##
647
- $bp_fields_passed[] = $field;
648
-
649
- }
650
-
651
- }
652
-
653
- // cwjordan: check for x profile fields we want update time for ##
654
- $bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '';
655
- $bp_fields_update_passed = array();
656
- if ( $bp_fields_update && is_array( $bp_fields_update ) ) {
657
-
658
- foreach( $bp_fields_update as $field ) {
659
-
660
- // reverse tidy ##
661
- $field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
662
-
663
- // add to array ##
664
- $bp_fields_update_passed[] = $field . " Update Date";
665
-
666
- }
667
-
668
- }
669
-
670
- // global wpdb object ##
671
- global $wpdb;
672
-
673
- // compile final fields list ##
674
- $fields = array_merge( $this->get_user_fields(), $this->get_special_fields(), $usermeta_fields, $bp_fields_passed, $bp_fields_update_passed );
675
-
676
- // test field array ##
677
- #$this->pr( $fields );
678
-
679
- // build the document headers ##
680
- $headers = array();
681
-
682
- foreach ( $fields as $key => $field ) {
683
-
684
- // rename programs field ##
685
- if ( $field == 'member_of_club' ){
686
- $field = 'Program';
687
- }
688
-
689
- // grab fields to exclude from exports ##
690
- if ( in_array( $field, $this->get_exclude_fields() ) ) {
691
-
692
- unset( $fields[$key] );
693
-
694
- } else {
695
-
696
- if ( $is_csv ) {
697
-
698
- $headers[] = '"' . $field . '"';
699
-
700
- } else {
701
-
702
- $headers[] = $field;
703
- #echo '<script>console.log("Echoing header cell: '.$field.'")</script>';
704
-
705
- }
706
-
707
- }
708
-
709
- }
710
-
711
- // no more buffering while spitting back the export data ##
712
- ob_end_flush();
713
-
714
- // get the value in bytes allocated for Memory via php.ini ##
715
- // @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
716
- $memory_limit = $this->return_bytes( ini_get('memory_limit') ) * .75;
717
-
718
- // we need to disable caching while exporting because we export so much data that it could blow the memory cache
719
- // if we can't override the cache here, we'll have to clear it later...
720
- if ( function_exists( 'override_function' ) ) {
721
-
722
- override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
723
- override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
724
- override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
725
- override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
726
-
727
- } elseif ( function_exists( 'runkit_function_redefine' ) ) {
728
-
729
- runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
730
- runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
731
- runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
732
- runkit_function_redefine('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
733
-
734
- }
735
-
736
- // open doc wrapper.. ##
737
- echo $doc_begin;
738
-
739
- // echo headers ##
740
- echo $pre . implode( $seperator, $headers ) . $breaker;
741
-
742
- // build row values for each user ##
743
- foreach ( $users as $user ) {
744
-
745
- // check if we're hitting any Memory limits, if so flush them out ##
746
- // per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
747
- if ( memory_get_usage( true ) > $memory_limit ) {
748
- wp_cache_flush();
749
- }
750
-
751
- // open up a new empty array ##
752
- $data = array();
753
-
754
- // BP loaded ? ##
755
- if ( function_exists ( 'bp_is_active' ) ) {
756
-
757
- #$bp_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID );
758
- $bp_data = self::get_all_for_user( $user->ID ); // taken from old BP method ##
759
-
760
- }
761
-
762
- // single query method - get all user_meta data ##
763
- $get_user_meta = (array)get_user_meta( $user->ID );
764
- #wp_die( $this->pr( $get_user_meta ) );
765
-
766
- // Filter out empty meta data ##
767
- #$get_user_meta = array_filter( array_map( function( $a ) {
768
- # return $a[0];
769
- #}, $get_user_meta ) );
770
-
771
- // loop over each field ##
772
- foreach ( $fields as $field ) {
773
-
774
- // check if this is a BP field ##
775
- if ( isset( $bp_data ) && isset( $bp_data[$field] ) && in_array( $field, $bp_fields_passed ) )
776
- {
777
-
778
- $value = $bp_data[$field];
779
-
780
- if ( is_array( $value ) ) {
781
-
782
- $value = maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
783
- #$value = $value['field_data'];
784
-
785
- /**
786
- * cwjordan
787
- * after unserializing it we then
788
- * need to implode it so
789
- * that we have something readable?
790
- * Going to use :: as a separator
791
- * because that's what Buddypress Members Import
792
- * expects, but we might want to make that
793
- * configurable.
794
- */
795
- if ( is_array( $value ) ) {
796
- $value = implode("::", $value );
797
- }
798
-
799
- }
800
-
801
- $value = $this->sanitize($value);
802
-
803
- // check if this is a BP field we want the updated date for ##
804
- }
805
- elseif ( in_array( $field, $bp_fields_update_passed ) )
806
- {
807
-
808
- global $bp;
809
-
810
- $real_field = str_replace(" Update Date", "", $field);
811
- $field_id = xprofile_get_field_id_from_name( $real_field );
812
- $value = $wpdb->get_var (
813
- $wpdb->prepare(
814
- "
815
- SELECT last_updated
816
- FROM {$bp->profile->table_name_data}
817
- WHERE user_id = %d AND field_id = %d
818
- "
819
- , $user->ID
820
- , $field_id
821
- )
822
- );
823
-
824
- // include the user's role in the export ##
825
- }
826
- elseif ( isset( $_POST['roles'] ) && $_POST['roles'] == '1' && $field == 'roles' )
827
- {
828
-
829
- // add "Role" as $value ##
830
- $value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
831
-
832
- // include the user's BP group in the export ##
833
- }
834
- elseif ( isset( $_POST['groups'] ) && $_POST['groups'] == '1' && $field == 'groups' )
835
- {
836
-
837
- if ( function_exists( 'groups_get_user_groups' ) ) {
838
-
839
- // check if user is a member of any groups ##
840
- $group_ids = groups_get_user_groups( $user->ID );
841
-
842
- if ( ! $group_ids || $group_ids == '' ) {
843
-
844
- $value = '';
845
-
846
- } else {
847
-
848
- // new empty array ##
849
- $groups = array();
850
-
851
- // loop over all groups ##
852
- foreach( $group_ids["groups"] as $group_id ) {
853
-
854
- $groups[] = groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
855
-
856
- }
857
-
858
- // implode it ##
859
- $value = implode( $groups, '|' );
860
-
861
- }
862
-
863
- } else {
864
-
865
- $value = '';
866
-
867
- }
868
-
869
- }
870
- elseif ( $field == 'bp_latest_update' )
871
- {
872
-
873
- // https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
874
- $value = bp_get_user_last_activity( $user->ID );
875
-
876
- // user or usermeta field ##
877
- }
878
- else
879
- {
880
-
881
- // the user_meta key isset ##
882
- if ( isset( $get_user_meta[$field] ) ) {
883
-
884
- // take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
885
- $value = $get_user_meta[$field][0];
886
-
887
- // standard WP_User value ##
888
- } else {
889
-
890
- // use the magically assigned value from WP_Users
891
- $value = $user->{$field};
892
-
893
- }
894
-
895
-
896
- // the $value might be serialized ##
897
- $value = self::unserialize( $value );
898
-
899
- // the value is an array ##
900
- if ( is_array ( $value ) ) {
901
-
902
- // recursive implode it ##
903
- $value = self::recursive_implode( $value );
904
-
905
- }
906
-
907
- }
908
-
909
-
910
- // correct program value to Program Name ##
911
- if ( $field == 'member_of_club' ) {
912
-
913
- $value = get_the_title($value);
914
-
915
- }
916
-
917
- // wrap values in quotes and add to array ##
918
- if ( $is_csv ) {
919
-
920
- $data[] = '"' . str_replace( '"', '""', $value ) . '"';
921
-
922
- // just add to array ##
923
- } else {
924
-
925
- $data[] = $value;
926
- }
927
-
928
- }
929
-
930
- // echo row data ##
931
- echo $pre . implode( $seperator, $data ) . $breaker;
932
-
933
- }
934
-
935
- // close doc wrapper..
936
- echo $doc_end;
937
-
938
- // stop PHP, so file can export correctly ##
939
- exit;
940
-
941
- }
942
-
943
-
944
- /**
945
- * Content of the settings page
946
- *
947
- * @since 0.1
948
- **/
949
- public function users_page()
950
- {
951
-
952
- // quick security check ##
953
- if ( ! current_user_can( 'list_users' ) ) {
954
-
955
- wp_die( __( 'You do not have sufficient permissions to access this page.', $this->text_domain ) );
956
-
957
- }
958
-
959
- // Save settings button was pressed ##
960
- if (
961
- isset( $_POST['save_export'] )
962
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
963
- ) {
964
-
965
- // start with an empty variable ##
966
- $save_export = "";
967
-
968
- if ( ! empty( $_POST['save_new_export_name'] ) ) {
969
-
970
- // assign value ##
971
- $save_export = $_POST['save_new_export_name'];
972
-
973
- } elseif ( ! empty( $_POST['export_name'] ) ) {
974
-
975
- $save_export = $_POST['export_name'];
976
-
977
- }
978
-
979
- // clean up $save_export ##
980
- $save_export = sanitize_text_field( $save_export );
981
-
982
- // Build array of $options to save and save them ##
983
- if ( isset( $save_export ) ) {
984
-
985
- // prepare all array values ##
986
- $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
987
- $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
988
- $bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '' ;
989
- $format = isset( $_POST['format'] ) ? $_POST['format'] : '' ;
990
- $role = isset( $_POST['role'] ) ? $_POST['role'] : '' ;
991
- $roles = isset( $_POST['roles'] ) ? $_POST['roles'] : '0' ;
992
- $groups = isset( $_POST['groups'] ) ? $_POST['groups'] : '0' ;
993
- $start_date = isset( $_POST['start_date'] ) ? $_POST['start_date'] : '' ;
994
- $end_date = isset( $_POST['end_date'] ) ? $_POST['end_date'] : '' ;
995
- $limit_offset = isset( $_POST['limit_offset'] ) ? $_POST['limit_offset'] : '' ;
996
- $limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
997
-
998
- // assign all values to an array ##
999
- $save_array = array (
1000
- 'usermeta_saved_fields' => $usermeta,
1001
- 'bp_fields_saved_fields' => $bp_fields,
1002
- 'bp_fields_update_time_saved_fields' => $bp_fields_update,
1003
- 'role' => $role,
1004
- 'roles' => $roles,
1005
- 'groups' => $groups,
1006
- 'start_date' => $start_date,
1007
- 'end_date' => $end_date,
1008
- 'limit_offset' => $limit_offset,
1009
- 'limit_total' => $limit_total,
1010
- 'format' => $format
1011
- );
1012
-
1013
- // store the options, for next load ##
1014
- $this->set_user_options( $save_export, $save_array );
1015
-
1016
- // Display the settings the user just saved instead of blanking the form ##
1017
- $_POST['load_export'] = 'Load Settings';
1018
- $_POST['export_name'] = $save_export;
1019
-
1020
- }
1021
-
1022
- }
1023
-
1024
- // Load settings button was pressed ( or option saved and $_POST variables hijacked )##
1025
- if (
1026
- isset( $_POST['load_export'] )
1027
- && isset( $_POST['export_name'] )
1028
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1029
- ) {
1030
-
1031
- $this->get_user_options_by_export( sanitize_text_field( $_POST['export_name'] ) );
1032
-
1033
- }
1034
-
1035
- // Delete settings button was pressed ##
1036
- if (
1037
- isset( $_POST['delete_export'] )
1038
- && isset( $_POST['export_name'] )
1039
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1040
- ) {
1041
-
1042
- $this->delete_user_options( sanitize_text_field( $_POST['export_name'] ) );
1043
-
1044
- }
1045
-
1046
- ?>
1047
- <div class="wrap">
1048
- <h2><?php _e( 'Export User Data', $this->text_domain ); ?></h2>
1049
- <?php
1050
-
1051
- // nothing happening? ##
1052
- if ( isset( $_GET['error'] ) ) {
1053
- echo '<div class="updated"><p><strong>' . __( 'No users found.', $this->text_domain ) . '</strong></p></div>';
1054
- }
1055
-
1056
- ?>
1057
- <form method="post" action="" enctype="multipart/form-data">
1058
- <?php wp_nonce_field( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' ); ?>
1059
- <table class="form-table">
1060
- <?php
1061
-
1062
- // allow admin to select user meta fields to export ##
1063
- global $wpdb;
1064
- $meta_keys = $wpdb->get_results( "SELECT distinct(meta_key) FROM $wpdb->usermeta" );
1065
-
1066
- // get meta_key value from object ##
1067
- $meta_keys = wp_list_pluck( $meta_keys, 'meta_key' );
1068
-
1069
- // let's note some of them odd keys ##
1070
- $meta_keys_system = array(
1071
- 'metaboxhidden',
1072
- 'activation',
1073
- 'bp_',
1074
- 'nav_',
1075
- 'wp_',
1076
- 'admin_color',
1077
- 'wpmudev',
1078
- 'screen_',
1079
- 'show_',
1080
- 'rich_',
1081
- 'reward_',
1082
- 'meta-box',
1083
- 'manageedit',
1084
- 'edit_',
1085
- 'closedpostboxes_',
1086
- 'dismissed_',
1087
- 'manage',
1088
- 'comment',
1089
- 'current',
1090
- 'incentive_',
1091
- '_wdp',
1092
- 'ssl',
1093
- 'wdfb',
1094
- 'users_per_page',
1095
- );
1096
-
1097
- // allow array to be filtered ##
1098
- $meta_keys_system = apply_filters( 'export_user_data_meta_keys_system', $meta_keys_system );
1099
-
1100
- // test array ##
1101
- #echo '<pre>'; var_dump($meta_keys); echo '</pre>';
1102
-
1103
- // check if we got anything ? ##
1104
- if ( $meta_keys ) {
1105
-
1106
- ?>
1107
- <tr valign="top">
1108
- <th scope="row">
1109
- <label for="q_eud_usermeta"><?php _e( 'User Meta Fields', $this->text_domain ); ?></label>
1110
- <p class="filter" style="margin: 10px 0 0;">
1111
- <?php _e('Filter', $this->text_domain); ?>: <a href="#" class="usermeta-all"><?php _e('All', $this->text_domain); ?></a> | <a href="#" class="usermeta-common"><?php _e('Common', $this->text_domain); ?></a>
1112
- </p>
1113
- <p class="filter" style="margin: 10px 0 0;">
1114
- <?php _e('Select', $this->text_domain); ?>: <a href="#" class="select-all"><?php _e('All', $this->text_domain); ?></a> | <a href="#" class="select-none"><?php _e('None', $this->text_domain); ?></a>
1115
- </p>
1116
- </th>
1117
- <td>
1118
- <select multiple="multiple" id="usermeta" name="usermeta[]">
1119
- <?php
1120
-
1121
- foreach ( $meta_keys as $key ) {
1122
-
1123
- #echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1124
-
1125
- // display $key ##
1126
- $display_key = $key;
1127
-
1128
- // rename programs field ##
1129
- if ( $display_key == 'member_of_club' ){
1130
- $display_key = 'program';
1131
- }
1132
-
1133
- // tidy ##
1134
- $display_key = str_replace( "_", " ", ucwords( $display_key ) );
1135
-
1136
- #echo "<label for='".esc_attr( $key )."' title='".esc_attr( $key )."'><input id='".esc_attr( $key )."' type='checkbox' name='usermeta[]' value='".esc_attr( $key )."'/> $display_key</label><br />";
1137
-
1138
- // class ##
1139
- $usermeta_class = 'normal';
1140
-
1141
- foreach ( $meta_keys_system as $drop ) {
1142
-
1143
- if ( strpos( $key, $drop ) !== false ) {
1144
-
1145
- // https://wordpress.org/support/topic/bugfix-numbers-in-export-headers?replies=1
1146
- // removed $key = assignment, as not required ##
1147
- if ( ( array_search( $key, $meta_keys ) ) !== false ) {
1148
-
1149
- $usermeta_class = 'system';
1150
-
1151
- }
1152
-
1153
- }
1154
-
1155
- }
1156
-
1157
- // print key ##
1158
- echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."' class='".$usermeta_class."'>$display_key</option>";
1159
-
1160
- }
1161
- ?>
1162
- </select>
1163
- <p class="description"><?php
1164
- printf(
1165
- __( 'Select the user meta keys to export, use the filters to simplify the list.', $this->text_domain )
1166
- );
1167
- ?></p>
1168
- </td>
1169
- </tr>
1170
- <?php
1171
-
1172
- } // meta_keys found ##
1173
-
1174
- ?>
1175
- <?php
1176
-
1177
- // buddypress x profile data ##
1178
- if ( function_exists ('bp_is_active') ) {
1179
-
1180
- // grab all buddypress x profile fields ##
1181
- $bp_fields = $wpdb->get_results( "SELECT distinct(name) FROM ".$wpdb->base_prefix."bp_xprofile_fields WHERE parent_id = 0" );
1182
-
1183
- // get name value from object ##
1184
- $bp_fields = wp_list_pluck( $bp_fields, 'name' );
1185
-
1186
- // test array ##
1187
- #echo '<pre>'; var_dump($bp_fields); echo '</pre>';
1188
-
1189
- // allow array to be filtered ##
1190
- $bp_fields = apply_filters( 'export_user_data_bp_fields', $bp_fields );
1191
-
1192
- ?>
1193
- <tr valign="top">
1194
- <th scope="row">
1195
- <label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields', $this->text_domain ); ?></label>
1196
- <p class="filter" style="margin: 10px 0 0;">
1197
- <?php _e('Select', $this->text_domain); ?>: <a href="#" class="select-all"><?php _e('All', $this->text_domain); ?></a> | <a href="#" class="select-none"><?php _e('None', $this->text_domain); ?></a>
1198
- </p>
1199
- </th>
1200
- <td>
1201
- <select multiple="multiple" id="bp_fields" name="bp_fields[]">
1202
- <?php
1203
-
1204
- foreach ( $bp_fields as $key ) {
1205
-
1206
- // tidy up key ##
1207
- $key_tidy = str_replace( ' ', '__', ($key));
1208
-
1209
- #echo "<label for='".esc_attr( $key_tidy )."'><input id='".esc_attr( $key_tidy )."' type='checkbox' name='bp_fields[]' value='".esc_attr( $key_tidy )."'/> $key</label><br />";
1210
-
1211
- // print key ##
1212
- echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
1213
-
1214
- }
1215
-
1216
- ?>
1217
- </select>
1218
- <p class="description"><?php
1219
- printf(
1220
- __( 'Select the BuddyPress XProfile keys to export', $this->text_domain )
1221
- );
1222
- ?></p>
1223
- </td>
1224
- </tr>
1225
- <?php
1226
-
1227
- // allow export of update times ##
1228
-
1229
- ?>
1230
- <tr valign="top" class="toggleable">
1231
- <th scope="row">
1232
- <label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields Update Time', $this->text_domain ); ?></label>
1233
- <p class="filter" style="margin: 10px 0 0;">
1234
- <?php _e('Select', $this->text_domain); ?>: <a href="#" class="select-all"><?php _e('All', $this->text_domain); ?></a> | <a href="#" class="select-none"><?php _e('None', $this->text_domain); ?></a>
1235
- </p>
1236
- </th>
1237
- <td>
1238
- <select multiple="multiple" id="bp_fields_update_time" name="bp_fields_update_time[]">
1239
- <?php
1240
-
1241
- foreach ( $bp_fields as $key ) {
1242
-
1243
- echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
1244
-
1245
- }
1246
-
1247
- ?>
1248
- </select>
1249
- <p class="description"><?php
1250
- printf(
1251
- __( 'Select the BuddyPress XProfile keys updated dates to export', $this->text_domain )
1252
- );
1253
- ?></p>
1254
- </td>
1255
- </tr>
1256
-
1257
- <tr valign="top" class="toggleable">
1258
- <th scope="row"><label for="groups"><?php _e( 'BP User Groups', $this->text_domain ); ?></label></th>
1259
- <td>
1260
- <input id='groups' type='checkbox' name='groups' value='1' <?php checked( isset ( $this->groups ) ? intval ( $this->groups ) : '', 1 ); ?> />
1261
- <p class="description"><?php
1262
- printf(
1263
- __( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', $this->text_domain )
1264
- , esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
1265
- , 'Codex'
1266
- );
1267
- ?></p>
1268
- </td>
1269
- </tr>
1270
- <?php
1271
-
1272
- } // BP installed and active ##
1273
-
1274
- ?>
1275
- <tr valign="top" class="toggleable">
1276
- <th scope="row"><label for="q_eud_users_role"><?php _e( 'Role', $this->text_domain ); ?></label></th>
1277
- <td>
1278
- <select name="role" id="q_eud_users_role">
1279
- <?php
1280
-
1281
- echo '<option value="">' . __( 'All Roles', $this->text_domain ) . '</option>';
1282
- global $wp_roles;
1283
-
1284
- foreach ( $wp_roles->role_names as $role => $name ) {
1285
-
1286
- if ( isset ( $this->role ) && ( $this->role == $role ) ) {
1287
-
1288
- echo "\n\t<option selected value='" . esc_attr( $role ) . "'>$name</option>";
1289
-
1290
- } else {
1291
-
1292
- echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1293
-
1294
- }
1295
- }
1296
-
1297
-
1298
- ?>
1299
- </select>
1300
- <p class="description"><?php
1301
- printf(
1302
- __( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', $this->text_domain )
1303
- , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1304
- , 'Codex'
1305
- );
1306
- ?></p>
1307
- </td>
1308
- </tr>
1309
-
1310
- <tr valign="top" class="toggleable">
1311
- <th scope="row"><label for="roles"><?php _e( 'User Roles', $this->text_domain ); ?></label></th>
1312
- <td>
1313
- <input id='roles' type='checkbox' name='roles' value='1' <?php checked( isset ( $this->roles ) ? intval ( $this->roles ) : '', 1 ); ?> />
1314
- <p class="description"><?php
1315
- printf(
1316
- __( 'Include all of the users <a href="%s" target="_blank">%s</a>', $this->text_domain )
1317
- , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1318
- , 'Roles'
1319
- );
1320
- ?></p>
1321
- </td>
1322
- </tr>
1323
- <?php
1324
-
1325
- // clubs ? ##
1326
- if ( post_type_exists( 'club' ) ) {
1327
-
1328
- ?>
1329
- <tr valign="top" class="toggleable">
1330
- <th scope="row"><label for="q_eud_users_program"><?php _e( 'Programs', $this->text_domain ); ?></label></th>
1331
- <td>
1332
- <select name="program" id="q_eud_users_program">
1333
- <?php
1334
-
1335
- echo '<option value="">' . __( 'All Programs', $this->text_domain ) . '</option>';
1336
-
1337
- $clubs_array = get_posts(array( 'post_type'=> 'club', 'posts_per_page' => -1 )); // grab all posts of type "club" ##
1338
-
1339
- foreach ( $clubs_array as $c ) { // loop over all clubs ##
1340
-
1341
- #$clubs[$c->ID] = $c; // grab club ID ##
1342
- echo "\n\t<option value='" . esc_attr( $c->ID ) . "'>$c->post_title</option>";
1343
-
1344
- }
1345
-
1346
- ?>
1347
- </select>
1348
- </td>
1349
- </tr>
1350
- <?php
1351
-
1352
- } // clubs ##
1353
-
1354
- ?>
1355
- <tr valign="top" class="toggleable">
1356
- <th scope="row"><label><?php _e( 'Registered', $this->text_domain ); ?></label></th>
1357
- <td>
1358
- <input type="text" id="q_eud_users_start_date" name="start_date" value="<?php echo $this->start_date; ?>" class="start-datepicker" />
1359
- <input type="text" id="q_eud_users_end_date" name="end_date" value="<?php echo $this->end_date; ?>" class="end-datepicker" />
1360
- <p class="description"><?php
1361
- printf(
1362
- __( 'Pick a start and end user registration date to limit the results.', $this->text_domain )
1363
- );
1364
- ?></p>
1365
- </td>
1366
- </tr>
1367
-
1368
- <tr valign="top" class="toggleable">
1369
- <th scope="row"><label><?php _e( 'Limit Range', $this->text_domain ); ?></label></th>
1370
- <td>
1371
- <input name="limit_offset" type="text" id="q_eud_users_limit_offset" value="<?php echo( $this->limit_offset ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Offset', $this->text_domain ); ?>">
1372
- <input name="limit_total" type="text" id="q_eud_users_limit_total" value="<?php echo ( $this->limit_total ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Total', $this->text_domain ); ?>">
1373
- <p class="description"><?php
1374
- printf(
1375
- __( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', $this->text_domain )
1376
- , esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
1377
- , 'Codex'
1378
- );
1379
- ?></p>
1380
- </td>
1381
- </tr>
1382
-
1383
- <tr valign="top">
1384
- <th scope="row"><label for="q_eud_users_format"><?php _e( 'Format', $this->text_domain ); ?></label></th>
1385
- <td>
1386
- <select name="format" id="q_eud_users_format">
1387
- <?php
1388
- if ( isset ( $this->format ) && ( $this->format == 'excel' ) ) {
1389
- echo '<option selected value="excel">' . __( 'Excel', $this->text_domain ) . '</option>';
1390
- } else {
1391
- echo '<option value="excel">' . __( 'Excel', $this->text_domain ) . '</option>';
1392
- }
1393
- if ( isset ( $this->format ) && ( $this->format == 'csv' ) ) {
1394
- echo '<option selected value="csv">' . __( 'CSV', $this->text_domain ) . '</option>';
1395
- } else {
1396
- echo '<option value="csv">' . __( 'CSV', $this->text_domain ) . '</option>';
1397
- }
1398
- ?>
1399
- </select>
1400
- <p class="description"><?php
1401
- printf(
1402
- __( 'Select the format for the export file.', $this->text_domain )
1403
- );
1404
- ?></p>
1405
- </td>
1406
- </tr>
1407
-
1408
- <tr valign="top" class="remember">
1409
- <th scope="row"><label for="q_eud_save_options"><?php _e( 'Stored Options', $this->text_domain ); ?></label></th>
1410
- <td>
1411
-
1412
- <div class="row">
1413
- <input type="text" class="regular-text" name="save_new_export_name" id="q_eud_save_options_new_export" placeholder="<?php _e( 'Export Name', $this->text_domain ); ?>" value="<?php echo isset( $_POST['export_name'] ) ? $_POST['export_name'] : '' ; ?>">
1414
- <input type="submit" id="save_export" class="button-primary" name="save_export" value="<?php _e( 'Save', $this->text_domain ); ?>" />
1415
- </div>
1416
- <?php
1417
-
1418
- // check if the user has any saved exports ##
1419
- if ( $this->get_user_options() ) {
1420
-
1421
- ?>
1422
- <div class="row">
1423
- <select name="export_name" id="q_eud_save_options" class="regular-text">
1424
- <?php
1425
-
1426
- // loop over each saved export ##
1427
- foreach( $this->get_user_options() as $export ) {
1428
-
1429
- // select Loaded export name, if selected ##
1430
- if (
1431
- isset( $_POST['load_export'] )
1432
- && isset( $_POST['export_name'] )
1433
- && ( $_POST['export_name'] == $export )
1434
- ) {
1435
-
1436
- echo "<option selected value='$export'>$export</option>";
1437
-
1438
- // just list previous export name ##
1439
- } else {
1440
-
1441
- echo "<option value='$export'>$export</option>";
1442
-
1443
- }
1444
-
1445
- }
1446
-
1447
- ?>
1448
- </select>
1449
-
1450
- <input type="submit" id="load_export" class="button-primary" name="load_export" value="<?php _e( 'Load', $this->text_domain ); ?>" />
1451
- <input type="submit" id="delete_export" class="button-primary" name="delete_export" value="<?php _e( 'Delete', $this->text_domain ); ?>" />
1452
- <?php
1453
-
1454
- }
1455
-
1456
- ?>
1457
- </div>
1458
- <p class="description"><?php _e( 'Save, load or delete your stored export options.', $this->text_domain ); ?></p>
1459
-
1460
- </td>
1461
- </tr>
1462
-
1463
- <tr valign="top">
1464
- <th scope="row">
1465
- <label for="q_eud_xprofile"><?php _e( 'Advanced Options', $this->text_domain ); ?></label>
1466
- </th>
1467
- <td>
1468
- <div class="toggle">
1469
- <a href="#"><?php _e( 'Show', $this->text_domain ); ?></a>
1470
- </div>
1471
- </td>
1472
- </tr>
1473
-
1474
- </table>
1475
- <p class="submit">
1476
- <input type="hidden" name="_wp_http_referer" value="<?php echo $_SERVER['REQUEST_URI'] ?>" />
1477
- <input type="submit" class="button-primary" value="<?php _e( 'Run Export', $this->text_domain ); ?>" />
1478
- </p>
1479
- </form>
1480
- </div>
1481
-
1482
- <?php
1483
- }
1484
-
1485
-
1486
- /**
1487
- * Inline jQuery
1488
- * @since 0.8.2
1489
- */
1490
- public function jquery()
1491
- {
1492
-
1493
- // load the scripts on only the plugin admin page
1494
- if (isset( $_GET['page'] ) && ( $_GET['page'] == $this->text_domain ) ) {
1495
- ?>
1496
- <script>
1497
-
1498
- // lazy load in some jQuery validation ##
1499
- jQuery(document).ready(function($) {
1500
-
1501
- // build super multiselect ##
1502
- jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
1503
-
1504
- //Select any fields from saved settings ##
1505
- jQuery('#usermeta').multiSelect('select',([<?php echo( $this->quote_array( $this->usermeta_saved_fields ) ); ?>]));
1506
- jQuery('#bp_fields').multiSelect('select',([<?php echo( $this->quote_array($this->bp_fields_saved_fields ) ); ?>]));
1507
- jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( $this->quote_array( $this->bp_fields_update_time_saved_fields ) ); ?>]));
1508
-
1509
- // show only common ##
1510
- jQuery('.usermeta-common').click(function(e){
1511
- e.preventDefault();
1512
- jQuery('#ms-usermeta .ms-selectable li.system').hide();
1513
- });
1514
-
1515
- // show all ##
1516
- jQuery('.usermeta-all').click(function(e){
1517
- e.preventDefault();
1518
- jQuery('#ms-usermeta .ms-selectable li').show();
1519
- });
1520
-
1521
- // select all ##
1522
- jQuery('.select-all').click(function(e){
1523
- e.preventDefault();
1524
- jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
1525
- });
1526
-
1527
- // select none ##
1528
- jQuery('.select-none').click(function(e){
1529
- e.preventDefault();
1530
- jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'deselect_all' );
1531
- });
1532
-
1533
-
1534
- // validate number inputs ##
1535
- $("input.numeric").blur(function() {
1536
-
1537
- //console.log("you entered "+ $(this).val());
1538
-
1539
- if ( $(this).val() && ! $.isNumeric( $(this).val() ) ) {
1540
-
1541
- //console.log("this IS NOT a number");
1542
- $(this).css({ 'background': 'red', 'color': 'white' }); // highlight error ##
1543
- $("p.submit .button-primary").attr('disabled','disabled'); // disable submit ##
1544
-
1545
- } else {
1546
-
1547
- $(this).css({ 'background': 'white', 'color': '#333' }); // remove error highlighting ##
1548
- $("p.submit .button-primary").removeAttr('disabled'); // enable submit ##
1549
-
1550
- }
1551
-
1552
- });
1553
-
1554
- // toggle advanced options ##
1555
- jQuery(".toggle a").click( function(e) {
1556
- e.preventDefault();
1557
- $toggleable = jQuery("tr.toggleable");
1558
- $toggleable.toggle();
1559
- if ( $toggleable.is(":visible") ) {
1560
- jQuery(this).text("<?php _e( 'Hide', $this->text_domain ); ?>");
1561
- } else {
1562
- jQuery(this).text("<?php _e( 'Show', $this->text_domain ); ?>");
1563
- }
1564
- });
1565
-
1566
- // validate save button ##
1567
- jQuery("#save_export").click( function(e) {
1568
-
1569
- // grab the value of the input ##
1570
- var q_eud_save_options_new_export = jQuery('#q_eud_save_options_new_export').val();
1571
-
1572
- if ( ! q_eud_save_options_new_export || q_eud_save_options_new_export == '' ) {
1573
-
1574
- e.preventDefault(); // stop things here ##
1575
- jQuery('#q_eud_save_options_new_export').addClass("error");
1576
-
1577
- }
1578
-
1579
- });
1580
-
1581
- // remove validation on focus ##
1582
- jQuery("body").on( 'focus', '#q_eud_save_options_new_export', function(e) {
1583
-
1584
- jQuery(this).removeClass("error");
1585
-
1586
- });
1587
-
1588
- <?php
1589
-
1590
- // method returns an object with "first" & "last" keys ##
1591
- $dates = self::get_user_registered_dates();
1592
-
1593
- ?>
1594
-
1595
- // start date picker ##
1596
- jQuery('.start-datepicker').datepicker( {
1597
- dateFormat : 'yy-mm-dd',
1598
- minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1599
- maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
1600
- } );
1601
-
1602
- // end date picker ##
1603
- jQuery('.end-datepicker').datepicker( {
1604
- dateFormat : 'yy-mm-dd',
1605
- minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1606
- maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
1607
- } );
1608
-
1609
- });
1610
-
1611
- </script>
1612
- <?php
1613
- }
1614
-
1615
- }
1616
-
1617
-
1618
- /**
1619
- * Inline CSS
1620
- * @since 0.8.2
1621
- */
1622
- public function css()
1623
- {
1624
-
1625
- // load the scripts on only the plugin admin page
1626
- if (isset( $_GET['page'] ) && ( $_GET['page'] == $this->text_domain ) ) {
1627
- ?>
1628
- <style>
1629
- .toggleable { display: none; }
1630
- .hidden { display: none; }
1631
- </style>
1632
- <?php
1633
- }
1634
-
1635
- }
1636
-
1637
-
1638
- /**
1639
- * Data to exclude from export
1640
- */
1641
- public function get_exclude_fields()
1642
- {
1643
-
1644
- $exclude_fields = array (
1645
- 'user_pass'
1646
- #, 'user_activation_key'
1647
- );
1648
-
1649
- return apply_filters( 'export_user_data_exclude_fields', $exclude_fields );
1650
-
1651
- }
1652
-
1653
-
1654
- /**
1655
- * Get the array of standard WP_User fields to return
1656
- */
1657
- public function get_user_fields()
1658
- {
1659
-
1660
- // exportable user data ##
1661
- $user_fields = array(
1662
- 'ID'
1663
- , 'user_login'
1664
- #, 'user_pass'
1665
- , 'user_nicename'
1666
- , 'user_email'
1667
- , 'user_url'
1668
- , 'user_registered'
1669
- #, 'user_activation_key'
1670
- , 'user_status'
1671
- , 'display_name'
1672
- );
1673
-
1674
- return apply_filters( 'export_user_data_user_fields', $user_fields );
1675
-
1676
- }
1677
-
1678
-
1679
- /**
1680
- * Get the array of special user fields to return
1681
- */
1682
- public function get_special_fields()
1683
- {
1684
-
1685
- // exportable user data ##
1686
- $special_fields = array(
1687
- 'roles' // list of WP Roles
1688
- , 'groups' // BP Groups
1689
- );
1690
-
1691
- return apply_filters( 'export_user_data_special_fields', $special_fields );
1692
-
1693
- }
1694
-
1695
-
1696
- /*
1697
- * Pre User Query
1698
- */
1699
- public function pre_user_query( $user_search )
1700
- {
1701
-
1702
- global $wpdb;
1703
-
1704
- $where = '';
1705
-
1706
- if ( ! empty( $_POST['start_date'] ) ) {
1707
-
1708
- $date = new DateTime( sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
1709
- $date_formatted = $date->format( 'Y-m-d H:i:s' );
1710
-
1711
- $where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
1712
-
1713
- }
1714
- if ( ! empty( $_POST['end_date'] ) ) {
1715
-
1716
- $date = new DateTime( sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
1717
- $date_formatted = $date->format( 'Y-m-d H:i:s' );
1718
-
1719
- $where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
1720
-
1721
- }
1722
-
1723
- if ( ! empty( $where ) ) {
1724
-
1725
- $user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
1726
-
1727
- }
1728
-
1729
- #wp_die( self::pr( $user_search ) );
1730
- return $user_search;
1731
-
1732
- }
1733
-
1734
-
1735
- /**
1736
- * Export Date Options
1737
- *
1738
- * @since 0.9.6
1739
- * @global type $wpdb
1740
- * @return Array of objects
1741
- */
1742
- private static function get_user_registered_dates()
1743
- {
1744
-
1745
- // invite in global objects ##
1746
- global $wpdb;
1747
-
1748
- // query user table for oldest and newest registration ##
1749
- $range =
1750
- $wpdb->get_results (
1751
- #$wpdb->prepare (
1752
- "
1753
- SELECT
1754
- MIN( user_registered ) AS first,
1755
- MAX( user_registered ) AS last
1756
- FROM
1757
- {$wpdb->users}
1758
- "
1759
- #)
1760
- );
1761
-
1762
- return $range;
1763
-
1764
- /*
1765
- // invite in global objects ##
1766
- global $wpdb, $wp_locale;
1767
-
1768
- // grab list of years and months available
1769
- $months = $wpdb->get_results( "
1770
- SELECT DISTINCT YEAR( user_registered ) AS year, MONTH( user_registered ) AS month, DAY( user_registered ) AS day
1771
- FROM $wpdb->users
1772
- ORDER BY user_registered DESC
1773
- " );
1774
-
1775
- // check if we got a result ##
1776
- $month_count = count( $months );
1777
-
1778
- // nothing cokking ##
1779
- if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
1780
-
1781
- return;
1782
-
1783
- }
1784
-
1785
- #wp_die( self::pr( $months ) );
1786
-
1787
- // loop over each month ##
1788
- foreach ( $months as $date ) {
1789
-
1790
- // skip if year == '0' ##
1791
- if ( 0 == $date->year ) {
1792
- continue;
1793
- }
1794
-
1795
- // make sure the month is in a MM two digit format ##
1796
- $month = zeroise( $date->month, 2 );
1797
-
1798
- // build up a tae string - YYYY-MM ##
1799
- $date_string = $date->year . '-' . $month;
1800
-
1801
- // check if passed date matches this string ##
1802
- if ( $selected_date == $date_string ) {
1803
-
1804
- ?>
1805
- <option selected value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1806
- <?php
1807
-
1808
- } else {
1809
-
1810
- ?>
1811
- <option value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1812
- <?php
1813
-
1814
- }
1815
-
1816
- }
1817
- */
1818
-
1819
- }
1820
-
1821
-
1822
- /**
1823
- * Quote array elements and separate with commas
1824
- *
1825
- * @since 0.9.6
1826
- * @return String
1827
- */
1828
- private function quote_array( $array )
1829
- {
1830
-
1831
- $prefix = ''; // starts empty ##
1832
- $elementlist = '';
1833
- if ( is_array( $array ) ) {
1834
- foreach( $array as $element ) {
1835
- $elementlist .= $prefix . "'" . $element . "'";
1836
- $prefix = ','; // prefix all remaining items with a comma ##
1837
- }
1838
- }
1839
-
1840
- // kick back string to function caller ##
1841
- return( $elementlist );
1842
-
1843
- }
1844
-
1845
-
1846
- /**
1847
- * Recursively implodes an array
1848
- *
1849
- * @since 1.0.1
1850
- * @access public
1851
- * @param array $array multi-dimensional array to recursively implode
1852
- * @param string $glue value that glues elements together
1853
- * @param bool $include_keys include keys before their values
1854
- * @param bool $trim_all trim ALL whitespace from string
1855
- * @return string imploded array
1856
- */
1857
- public static function recursive_implode( $array, $return = null, $glue = '|' )
1858
- {
1859
-
1860
- // unserialize ##
1861
- $array = self::unserialize( $array );
1862
-
1863
- // kick it back ##
1864
- if ( is_null ( $return ) && ! is_array( $array ) ) {
1865
-
1866
- return $array;
1867
-
1868
- }
1869
-
1870
- // empty return ##
1871
- if ( is_null ( $return ) ) {
1872
-
1873
- $return = '';
1874
-
1875
- } else {
1876
-
1877
- if ( "||" == $glue ) {
1878
-
1879
- $glue = '|||';
1880
-
1881
- } else if ( "|" == $glue ) {
1882
-
1883
- $glue = '||';
1884
-
1885
- }
1886
-
1887
- }
1888
-
1889
- // loop ##
1890
- foreach( $array as $key => $value ) {
1891
-
1892
- // unserialize ##
1893
- $value = self::unserialize( $value );
1894
-
1895
- if( is_array( $value ) ) {
1896
-
1897
- $return .= $glue . $key . $glue . self::recursive_implode( $value, $return, $glue );
1898
-
1899
- } else {
1900
-
1901
- $return .= $glue . $key . $glue . $value;
1902
-
1903
- }
1904
-
1905
- }
1906
-
1907
- // Removes first $glue from string ##
1908
- if ( $glue && $return && $return[0] == '|' ) {
1909
-
1910
- $return = ltrim ( $return, '|' );
1911
-
1912
- }
1913
-
1914
- // Trim ALL whitespace ##
1915
- if ( $return ) {
1916
-
1917
- $return = preg_replace( "/(\s)/ixsm", '', $return );
1918
-
1919
- }
1920
-
1921
- // kick it back ##
1922
- return $return;
1923
-
1924
- }
1925
-
1926
-
1927
-
1928
- /**
1929
- * Save Unserializer
1930
- *
1931
- * @since 1.1.4
1932
- */
1933
- public function unserialize( $value )
1934
- {
1935
-
1936
- // the $value is serialized ##
1937
- if ( is_serialized( $value ) ) {
1938
-
1939
- // unserliaze to new variable ##
1940
- $unserialized = @unserialize( $value );
1941
-
1942
- // test if unserliazing produced errors ##
1943
- if ( $unserialized !== false || $value == 'b:0;' ) {
1944
-
1945
- #$value = 'UNSERIALIZED_'.$unserialized;
1946
- $value = $unserialized;
1947
-
1948
- } else {
1949
-
1950
- // failed to unserialize - data potentially corrupted in db ##
1951
- #$value = 'NOT_SERIALIZED_'.$value;
1952
- $value = $value;
1953
-
1954
- }
1955
-
1956
- }
1957
-
1958
- // kick it back ##
1959
- return $value;
1960
-
1961
- }
1962
-
1963
-
1964
- /**
1965
- * Nicer var_dump
1966
- *
1967
- * @since 0.9.6
1968
- */
1969
- public function pr ( $variable )
1970
- {
1971
- echo '<pre>';
1972
- print_r ( $variable );
1973
- echo '</pre>';
1974
- }
1975
-
1976
-
1977
- }
1978
-
1979
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin Name: Export User Data
5
+ Plugin URI: http://qstudio.us/plugins/
6
+ Description: Export User data, metadata and BuddyPress X-Profile data.
7
+ Version: 1.2.1
8
+ Author: Q Studio
9
+ Author URI: http://qstudio.us
10
+ License: GPL2
11
+ Text Domain: export-user-data
12
+ */
13
+
14
+ // quick check :) ##
15
+ defined( 'ABSPATH' ) OR exit;
16
+
17
+ // Increase maximum execution time to prevent "Maximum execution time
18
+ // exceeded" error
19
+ ini_set('max_execution_time', 3600);
20
+
21
+ /* Check for Class */
22
+ if ( ! class_exists( 'Q_Export_User_Data' ) )
23
+ {
24
+
25
+ // plugin version
26
+ define( 'Q_EXPORT_USER_DATA_VERSION', '1.2.1' ); // version ##
27
+
28
+ // instatiate class via hook, only if inside admin
29
+ if ( is_admin() ) {
30
+
31
+ // instatiate plugin via WP hook - not too early, not too late ##
32
+ add_action( 'init', array ( 'Q_Export_User_Data', 'get_instance' ), 100000000 );
33
+
34
+ }
35
+
36
+
37
+ /**
38
+ * Main plugin class
39
+ *
40
+ * @since 0.1
41
+ **/
42
+ class Q_Export_User_Data {
43
+
44
+ // debug ##
45
+ const debug = true;
46
+
47
+ // Refers to a single instance of this class. ##
48
+ private static $instance = null;
49
+
50
+ /* properties */
51
+ public $text_domain = 'export-user-data'; // for translation ##
52
+ private $q_eud_exports = ''; // export settings ##
53
+ private $usermeta_saved_fields = array();
54
+ private $bp_fields_saved_fields = array();
55
+ private $bp_fields_update_time_saved_fields = array();
56
+ private $role = '';
57
+ private $roles = '1';
58
+ private $groups = '1';
59
+ private $start_date = '';
60
+ private $end_date = '';
61
+ private $limit_offset = '';
62
+ private $limit_total = '';
63
+ private $updated_since_date = '';
64
+ private $field_updated_since = '';
65
+ private $format = '';
66
+
67
+
68
+ /**
69
+ * Creates or returns an instance of this class.
70
+ *
71
+ * @return Foo A single instance of this class.
72
+ */
73
+ public static function get_instance() {
74
+
75
+ if ( null == self::$instance ) {
76
+ self::$instance = new self;
77
+ }
78
+
79
+ return self::$instance;
80
+
81
+ }
82
+
83
+
84
+ /**
85
+ * Class contructor
86
+ *
87
+ * @since 0.1
88
+ **/
89
+ private function __construct()
90
+ {
91
+
92
+ if ( is_admin() ) {
93
+
94
+ add_action( 'init', array( $this, 'load_plugin_textdomain' ), 100000001 );
95
+ add_action( 'init', array( $this, 'load_user_options' ), 100000002 );
96
+ add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
97
+ add_action( 'init', array( $this, 'generate_data' ), 100000003 );
98
+ add_filter( 'q_eud_exclude_data', array( $this, 'exclude_data' ) );
99
+ add_action( 'admin_enqueue_scripts', array( $this, 'add_css_and_js' ), 1 );
100
+ add_action( 'admin_footer', array( $this, 'jquery' ), 100000 );
101
+ add_action( 'admin_footer', array( $this, 'css' ), 100000 );
102
+
103
+ }
104
+
105
+ }
106
+
107
+
108
+ /**
109
+ * Load plugin text-domain
110
+ *
111
+ * @since 0.9.0
112
+ * @return void
113
+ **/
114
+ public function load_plugin_textdomain()
115
+ {
116
+
117
+ load_plugin_textdomain( 'export-user-data', false, basename( dirname( __FILE__ ) ) . '/languages' );
118
+
119
+ }
120
+
121
+
122
+ /**
123
+ * Write to WP Error Log
124
+ *
125
+ * @since 1.2.1
126
+ * @return void
127
+ */
128
+ public static function log( $log )
129
+ {
130
+ if ( true === WP_DEBUG ) {
131
+ if ( is_array( $log ) || is_object( $log ) ) {
132
+ error_log( print_r( $log, true ) );
133
+ } else {
134
+ error_log( $log );
135
+ }
136
+ }
137
+ }
138
+
139
+
140
+ /**
141
+ * Add administration menus
142
+ *
143
+ * @since 0.1
144
+ **/
145
+ public function add_admin_pages()
146
+ {
147
+
148
+ add_users_page( __( 'Export User Data', 'export-user-data' ), __( 'Export User Data', 'export-user-data' ), 'list_users', 'export-user-data', array( $this, 'users_page' ) );
149
+
150
+ }
151
+
152
+
153
+ /**
154
+ * style and interaction
155
+ */
156
+ public function add_css_and_js( $hook )
157
+ {
158
+
159
+ // load the scripts on only the plugin admin page ##
160
+ if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
161
+
162
+ wp_register_style( 'q_export_user_data', plugins_url( 'css/export-user-data.css' ,__FILE__ ));
163
+ wp_enqueue_style( 'q_export_user_data' );
164
+ wp_enqueue_script( 'q_eud_multi_select_js', plugins_url( 'js/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
165
+
166
+ // add script ##
167
+ wp_enqueue_script('jquery-ui-datepicker');
168
+
169
+ // add style ##
170
+ wp_enqueue_style( 'jquery-ui-datepicker' );
171
+ wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
172
+
173
+ }
174
+
175
+ }
176
+
177
+
178
+ /**
179
+ * Return Byte count of $val
180
+ *
181
+ * @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
182
+ * @since 0.9.6
183
+ */
184
+ public function return_bytes( $val )
185
+ {
186
+
187
+ $val = trim( $val );
188
+ $last = strtolower($val[strlen($val)-1]);
189
+ switch( $last ) {
190
+
191
+ // The 'G' modifier is available since PHP 5.1.0
192
+ case 'g':
193
+
194
+ $val *= 1024;
195
+
196
+ case 'm':
197
+
198
+ $val *= 1024;
199
+
200
+ case 'k':
201
+
202
+ $val *= 1024;
203
+
204
+ }
205
+
206
+ return $val;
207
+ }
208
+
209
+
210
+ /**
211
+ * clean that stuff up
212
+ */
213
+ public static function sanitize( $value )
214
+ {
215
+
216
+ $value = str_replace("\r", '', $value);
217
+ $value = str_replace("\n", '', $value);
218
+ $value = str_replace("\t", '', $value);
219
+ return $value;
220
+
221
+ }
222
+
223
+
224
+ /**
225
+ * Load up saved exports for this user
226
+ *
227
+ * @since 0.9.6
228
+ * @return Array of saved exports
229
+ */
230
+ public function load_user_options()
231
+ {
232
+
233
+
234
+ $this->q_eud_exports = get_user_meta( get_current_user_id(), 'q_eud_exports' ) ? get_user_meta( get_current_user_id(), 'q_eud_exports', true ) : array() ;
235
+ #var_dump( $this->q_eud_exports );
236
+
237
+ }
238
+
239
+
240
+ /**
241
+ * Get list of saved exports for this user
242
+ *
243
+ * @since 0.9.4
244
+ * @return Array of saved exports
245
+ */
246
+ public function get_user_options()
247
+ {
248
+
249
+ // get the stored options - filter empty array items ##
250
+ $q_eud_exports = array_filter( $this->q_eud_exports );
251
+
252
+ // quick check if the array is empty ##
253
+ if ( empty ( $q_eud_exports ) ) {
254
+
255
+ return false;
256
+
257
+ }
258
+
259
+ // test the array of saved exports ##
260
+ #$this->pr( $q_eud_exports );
261
+
262
+ // start with an empty array ##
263
+ $exports = array();
264
+
265
+ // loop over each saved export and grab each key ##
266
+ foreach ( $q_eud_exports as $key => $value ) {
267
+
268
+ $exports[] = $key;
269
+
270
+ }
271
+
272
+ // kick back array ##
273
+ return( $exports );
274
+
275
+ }
276
+
277
+
278
+ /**
279
+ * Check for and load stored user options
280
+ *
281
+ * @since 0.9.3
282
+ * @return void
283
+ */
284
+ public function get_user_options_by_export( $export = null )
285
+ {
286
+
287
+ // sanity check ##
288
+ if ( is_null ( $export ) ) { return false; }
289
+
290
+ if ( isset( $this->q_eud_exports[$export] ) ) {
291
+
292
+ $this->usermeta_saved_fields = $this->q_eud_exports[$export]['usermeta_saved_fields'];
293
+ $this->bp_fields_saved_fields = $this->q_eud_exports[$export]['bp_fields_saved_fields'];
294
+ $this->bp_fields_update_time_saved_fields = $this->q_eud_exports[$export]['bp_fields_update_time_saved_fields'];
295
+ $this->updated_since_date = $this->q_eud_exports[$export]['updated_since_date'];
296
+ $this->field_updated_since = $this->q_eud_exports[$export]['field_updated_since'];
297
+ $this->role = $this->q_eud_exports[$export]['role'];
298
+ $this->roles = $this->q_eud_exports[$export]['roles'];
299
+ $this->groups = $this->q_eud_exports[$export]['groups'];
300
+ $this->start_date = $this->q_eud_exports[$export]['start_date'];
301
+ $this->end_date = $this->q_eud_exports[$export]['end_date'];
302
+ $this->limit_offset = $this->q_eud_exports[$export]['limit_offset'];
303
+ $this->limit_total = $this->q_eud_exports[$export]['limit_total'];
304
+ $this->format = $this->q_eud_exports[$export]['format'];
305
+
306
+ } else {
307
+
308
+ $this->usermeta_saved_fields = array();
309
+ $this->bp_fields_saved_fields = array();
310
+ $this->bp_fields_update_time_saved_fields = array();
311
+ $this->updated_since_date = '';
312
+ $this->field_updated_since = '';
313
+ $this->role = '';
314
+ $this->roles = '1';
315
+ $this->groups = '1';
316
+ $this->start_date = '';
317
+ $this->end_date = '';
318
+ $this->limit_offset = '';
319
+ $this->limit_total = '';
320
+ $this->format = '';
321
+
322
+ }
323
+
324
+ }
325
+
326
+
327
+ /**
328
+ * method to store user options
329
+ *
330
+ * @param string $save_export Export Key name
331
+ * @param array $save_options Array of export options to save
332
+ * @since 0.9.3
333
+ * @return void
334
+ */
335
+ public function set_user_options( $key = null, $options = null )
336
+ {
337
+
338
+ // sanity check ##
339
+ if ( is_null ( $key ) || is_null ( $options ) ) {
340
+
341
+ #$this->pr( 'missing save values' );
342
+ return false;
343
+
344
+ }
345
+
346
+ #$this->pr( $key );
347
+ #$this->pr( $options );
348
+
349
+ // for now, I'm simply allowing keys to be resaved - but this is not so logical ##
350
+ if ( array_key_exists( $key, $this->q_eud_exports ) ) {
351
+
352
+ #$this->pr( 'key exists, skipping save' );
353
+ #return false;
354
+
355
+ }
356
+
357
+ if ( isset( $options ) && is_array( $options ) ) {
358
+
359
+ // update_option sanitizes the option name but not the option value ##
360
+ foreach ( $options as $field_name => $field_value ) {
361
+
362
+ // so do that here. ##
363
+ if ( is_array( $field_value ) ) {
364
+
365
+ foreach ( $field_value as $field_array_key => $field_array_value ) {
366
+
367
+ $options[$field_name][$field_array_key] = sanitize_text_field( $field_array_value );
368
+
369
+ }
370
+
371
+ } else {
372
+
373
+ $options[$field_name] = sanitize_text_field( $field_value );
374
+
375
+ }
376
+
377
+ }
378
+
379
+ // assign the sanitized array of values to the class property $q_eud_exports as a new array with key $key ##
380
+ $this->q_eud_exports[$key] = $options;
381
+
382
+ // update stored user_meta values, if previous key found ##
383
+ if ( get_user_meta( get_current_user_id(), 'q_eud_exports' ) !== false ) {
384
+
385
+ #update_option( 'q_eud_exports', $this->q_eud_exports );
386
+ update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
387
+
388
+ // create new user meta key ##
389
+ } else {
390
+
391
+ #add_option( 'q_eud_exports', $this->q_eud_exports, $deprecated, $autoload );
392
+ add_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
393
+
394
+ }
395
+
396
+ }
397
+
398
+ }
399
+
400
+
401
+ /**
402
+ * method to delete user options
403
+ *
404
+ * @param $key String Key name to drop from property
405
+ * @since 0.9.3
406
+ * @return void
407
+ */
408
+ public function delete_user_options( $key = null )
409
+ {
410
+
411
+ // sanity check ##
412
+ if ( is_null ( $key ) || ! array_key_exists( $key, $this->q_eud_exports ) ) { return false; }
413
+
414
+ // clean it up ##
415
+ $key = sanitize_text_field( $key );
416
+
417
+ // check it out ##
418
+ #$this->pr( $key );
419
+
420
+ // drop the array by it's key name from the class property ##
421
+ unset( $this->q_eud_exports[$key] );
422
+
423
+ // update the saved data ##
424
+ update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
425
+
426
+ }
427
+
428
+
429
+ /**
430
+ * Copy of BP_XProfile_ProfileData::get_all_for_user() from BP version 2.0?
431
+ * Get all of the profile information for a specific user.
432
+ *
433
+ * @param $user_id Integer ID of specific user
434
+ * @since 0.9.6
435
+ * @return Array User profile fields
436
+ */
437
+ private static function get_all_for_user( $user_id = null )
438
+ {
439
+
440
+ // sanity check ##
441
+ if ( is_null( $user_id ) ) { return false; }
442
+
443
+ global $wpdb, $bp;
444
+
445
+ $bp = buddypress();
446
+
447
+ $results = $wpdb->get_results(
448
+ $wpdb->prepare(
449
+ "
450
+ SELECT g.id as field_group_id, g.name as field_group_name, f.id as field_id, f.name as field_name, f.type as field_type, d.value as field_data, u.user_login, u.user_nicename, u.user_email
451
+ FROM {$bp->profile->table_name_groups} g
452
+ LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id
453
+ INNER JOIN {$bp->profile->table_name_data} d ON f.id = d.field_id LEFT JOIN {$wpdb->users} u ON d.user_id = u.ID
454
+ WHERE d.user_id = %d AND d.value != ''
455
+ "
456
+ , $user_id
457
+ )
458
+ );
459
+
460
+ $profile_data = array();
461
+
462
+ if ( ! empty( $results ) ) {
463
+
464
+ $profile_data['user_login'] = $results[0]->user_login;
465
+ $profile_data['user_nicename'] = $results[0]->user_nicename;
466
+ $profile_data['user_email'] = $results[0]->user_email;
467
+
468
+ foreach( (array) $results as $field ) {
469
+
470
+ $profile_data[$field->field_name] = array(
471
+ 'field_group_id' => $field->field_group_id,
472
+ 'field_group_name' => $field->field_group_name,
473
+ 'field_id' => $field->field_id,
474
+ 'field_type' => $field->field_type,
475
+ 'field_data' => $field->field_data
476
+ );
477
+
478
+ }
479
+
480
+ }
481
+
482
+ return $profile_data;
483
+
484
+ }
485
+
486
+
487
+ /**
488
+ * Process content of CSV file
489
+ *
490
+ * @since 0.1
491
+ **/
492
+ public function generate_data()
493
+ {
494
+
495
+ // Check if the user clicked on the Save, Load, or Delete Settings buttons ##
496
+ if (
497
+ ! isset( $_POST['_wpnonce-q-eud-export-user-page_export'] )
498
+ || isset( $_POST['load_export'] )
499
+ || isset( $_POST['save_export'] )
500
+ || isset( $_POST['delete_export'] ) )
501
+ {
502
+
503
+ return false;
504
+
505
+ }
506
+
507
+ // check admin referer ##
508
+ check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' );
509
+
510
+ // build argument array ##
511
+ $args = array(
512
+ 'fields' => 'all',
513
+ 'role' => sanitize_text_field( $_POST['role'] )
514
+ );
515
+
516
+ // did they request a specific program ? ##
517
+ if ( isset( $_POST['program'] ) && $_POST['program'] != '' ) {
518
+
519
+ $args['meta_key'] = 'member_of_club';
520
+ $args['meta_value'] = (int)$_POST['program'];
521
+ $args['meta_compare'] = '=';
522
+
523
+ }
524
+
525
+ // is there a range limit in place for the export ? ##
526
+ if ( isset( $_POST['limit_total'] ) && $_POST['limit_total'] != '' ) {
527
+
528
+ // let's just make sure they are integer values ##
529
+ $limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
530
+ $limit_total = (int)$_POST['limit_total'];
531
+
532
+ if ( is_int( $limit_offset ) && is_int( $limit_total ) ) {
533
+
534
+ $args['offset'] = $limit_offset;
535
+ $args['number'] = $limit_total; // number - Limit the total number of users returned ##
536
+
537
+ // test it ##
538
+ #wp_die( $this->pr( $args ) );
539
+
540
+ }
541
+
542
+ }
543
+
544
+ // pre_user query ##
545
+ add_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
546
+ $users = get_users( $args );
547
+ remove_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
548
+
549
+ // test args ##
550
+ #wp_die( $this->pr ( $users ) );
551
+
552
+ // no users found, so chuck an error into the args array and exit the export ##
553
+ if ( ! $users ) {
554
+
555
+ wp_redirect( add_query_arg( 'error', 'empty', wp_get_referer() ) );
556
+ exit;
557
+
558
+ }
559
+
560
+ // get sitename and clean it up ##
561
+ $sitename = sanitize_key( get_bloginfo( 'name' ) );
562
+ if ( ! empty( $sitename ) ) {
563
+ $sitename .= '.';
564
+ }
565
+
566
+ // export method ? ##
567
+ $export_method = 'excel'; // default to Excel export ##
568
+ if ( isset( $_POST['format'] ) && $_POST['format'] != '' ) {
569
+
570
+ $export_method = sanitize_text_field( $_POST['format'] );
571
+
572
+ }
573
+
574
+ // set export filename structure ##
575
+ $filename = $sitename . 'users.' . date( 'Y-m-d-H-i-s' );
576
+
577
+ switch ( $export_method ) {
578
+
579
+ case ( 'csv' ):
580
+
581
+ // to csv ##
582
+ header( 'Content-Description: File Transfer' );
583
+ header( 'Content-Disposition: attachment; filename='.$filename.'.csv' );
584
+ header( 'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ), true );
585
+
586
+ // set a csv check flag
587
+ $is_csv = true;
588
+
589
+ // nothing here
590
+ $doc_begin = '';
591
+
592
+ //preformat
593
+ $pre = '';
594
+
595
+ // how to seperate data ##
596
+ $seperator = ','; // comma for csv ##
597
+
598
+ // line break ##
599
+ $breaker = "\n";
600
+
601
+ // nothing here
602
+ $doc_end = '';
603
+
604
+ break;
605
+
606
+ case ( 'excel' ):
607
+
608
+ // to xls ##
609
+ header( 'Content-Description: File Transfer' );
610
+ header("Content-Type: application/vnd.ms-excel");
611
+ header("Content-Disposition: attachment; filename=$filename.xls");
612
+ header("Pragma: no-cache");
613
+ header("Expires: 0");
614
+
615
+ // set a csv check flag
616
+ $is_csv = false;
617
+
618
+ //grab the template file (for tidy formatting)
619
+ include( 'xml-template.php' );
620
+
621
+ // open xml
622
+ $doc_begin = $xml_doc_begin;
623
+
624
+ //preformat
625
+ $pre = $xml_pre;
626
+
627
+ // how to seperate data ##
628
+ $seperator = $xml_seperator;
629
+
630
+ // line break ##
631
+ $breaker = $xml_breaker;
632
+
633
+ // close xml
634
+ $doc_end = $xml_doc_end;
635
+
636
+ break;
637
+
638
+ }
639
+
640
+
641
+ // check for selected usermeta fields ##
642
+ $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
643
+ #$this->pr( $usermeta );
644
+ $usermeta_fields = array();
645
+
646
+ if ( $usermeta && is_array( $usermeta ) ) {
647
+ foreach( $usermeta as $field ) {
648
+ $usermeta_fields[] = sanitize_text_field ( $field );
649
+ }
650
+ }
651
+
652
+ #$this->pr( $usermeta_fields );
653
+ #exit;
654
+
655
+ // check for selected x profile fields ##
656
+ $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '';
657
+ $bp_fields_passed = array();
658
+ if ( $bp_fields && is_array( $bp_fields ) ) {
659
+
660
+ foreach( $bp_fields as $field ) {
661
+
662
+ // reverse tidy ##
663
+ $field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
664
+
665
+ // add to array ##
666
+ $bp_fields_passed[] = $field;
667
+
668
+ }
669
+
670
+ }
671
+
672
+ // cwjordan: check for x profile fields we want update time for ##
673
+ $bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '';
674
+ $bp_fields_update_passed = array();
675
+ if ( $bp_fields_update && is_array( $bp_fields_update ) ) {
676
+
677
+ foreach( $bp_fields_update as $field ) {
678
+
679
+ // reverse tidy ##
680
+ $field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
681
+
682
+ // add to array ##
683
+ $bp_fields_update_passed[] = $field . " Update Date";
684
+
685
+ }
686
+
687
+ }
688
+
689
+ // global wpdb object ##
690
+ global $wpdb;
691
+
692
+ // compile final fields list ##
693
+ $fields = array_merge( $this->get_user_fields(), $this->get_special_fields(), $usermeta_fields, $bp_fields_passed, $bp_fields_update_passed );
694
+
695
+ // test field array ##
696
+ #$this->pr( $fields );
697
+
698
+ // build the document headers ##
699
+ $headers = array();
700
+
701
+ foreach ( $fields as $key => $field ) {
702
+
703
+ // rename programs field ##
704
+ if ( $field == 'member_of_club' ){
705
+ $field = 'Program';
706
+ }
707
+
708
+ // grab fields to exclude from exports ##
709
+ if ( in_array( $field, $this->get_exclude_fields() ) ) {
710
+
711
+ unset( $fields[$key] );
712
+
713
+ } else {
714
+
715
+ if ( $is_csv ) {
716
+
717
+ $headers[] = '"' . $field . '"';
718
+
719
+ } else {
720
+
721
+ $headers[] = $field;
722
+ #echo '<script>console.log("Echoing header cell: '.$field.'")</script>';
723
+
724
+ }
725
+
726
+ }
727
+
728
+ }
729
+
730
+ // quick check ##
731
+ #if ( self::debug ) self::log( 'All Fields: '. var_dump( $fields ) );
732
+ #if ( self::debug ) self::log( '$bp_fields_passed: '. var_dump( $bp_fields_passed ) );
733
+
734
+ // no more buffering while spitting back the export data ##
735
+ ob_end_flush();
736
+
737
+ // get the value in bytes allocated for Memory via php.ini ##
738
+ // @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
739
+ $memory_limit = $this->return_bytes( ini_get('memory_limit') ) * .75;
740
+
741
+ // we need to disable caching while exporting because we export so much data that it could blow the memory cache
742
+ // if we can't override the cache here, we'll have to clear it later...
743
+ if ( function_exists( 'override_function' ) ) {
744
+
745
+ override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
746
+ override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
747
+ override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
748
+ override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
749
+
750
+ } elseif ( function_exists( 'runkit_function_redefine' ) ) {
751
+
752
+ runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
753
+ runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
754
+ runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
755
+ runkit_function_redefine('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
756
+
757
+ }
758
+
759
+ // open doc wrapper.. ##
760
+ echo $doc_begin;
761
+
762
+ // echo headers ##
763
+ echo $pre . implode( $seperator, $headers ) . $breaker;
764
+
765
+ // build row values for each user ##
766
+ foreach ( $users as $user ) {
767
+
768
+ // check if we're hitting any Memory limits, if so flush them out ##
769
+ // per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
770
+ if ( memory_get_usage( true ) > $memory_limit ) {
771
+ wp_cache_flush();
772
+ }
773
+
774
+ // open up a new empty array ##
775
+ $data = array();
776
+
777
+ #wp_die( self::pr( $GLOBALS['bp'] ) );
778
+
779
+ // BP loaded ? ##
780
+ if ( function_exists ( 'bp_is_active' ) && bp_is_active( 'xprofile' ) ) {
781
+
782
+ // grab all user data ##
783
+ $bp_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID );
784
+
785
+ }
786
+
787
+ // single query method - get all user_meta data ##
788
+ $get_user_meta = (array)get_user_meta( $user->ID );
789
+ #wp_die( self::pr( $get_user_meta ) );
790
+
791
+ // Filter out empty meta data ##
792
+ #$get_user_meta = array_filter( array_map( function( $a ) {
793
+ # return $a[0];
794
+ #}, $get_user_meta ) );
795
+
796
+ // loop over each field ##
797
+ foreach ( $fields as $field ) {
798
+
799
+ // check if this is a BP field ##
800
+ if ( isset( $bp_data ) && isset( $bp_data[$field] ) && in_array( $field, $bp_fields_passed ) )
801
+ {
802
+
803
+ // old way from single BP query ##
804
+ $value = $bp_data[$field];
805
+
806
+ if ( is_array( $value ) ) {
807
+
808
+ $value = maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
809
+ #$value = $value['field_data'];
810
+
811
+ /**
812
+ * cwjordan
813
+ * after unserializing it we then
814
+ * need to implode it so
815
+ * that we have something readable?
816
+ * Going to use :: as a separator
817
+ * because that's what Buddypress Members Import
818
+ * expects, but we might want to make that
819
+ * configurable.
820
+ */
821
+ if ( is_array( $value ) ) {
822
+ $value = implode("::", $value );
823
+ }
824
+
825
+ }
826
+
827
+ $value = self::sanitize($value);
828
+
829
+ // check if this is a BP field we want the updated date for ##
830
+ }
831
+ elseif ( in_array( $field, $bp_fields_update_passed ) )
832
+ {
833
+
834
+ global $bp;
835
+
836
+ $real_field = str_replace(" Update Date", "", $field);
837
+ $field_id = xprofile_get_field_id_from_name( $real_field );
838
+ $value = $wpdb->get_var (
839
+ $wpdb->prepare(
840
+ "
841
+ SELECT last_updated
842
+ FROM {$bp->profile->table_name_data}
843
+ WHERE user_id = %d AND field_id = %d
844
+ "
845
+ , $user->ID
846
+ , $field_id
847
+ )
848
+ );
849
+
850
+ // include the user's role in the export ##
851
+ }
852
+ elseif ( isset( $_POST['roles'] ) && $_POST['roles'] == '1' && $field == 'roles' )
853
+ {
854
+
855
+ // add "Role" as $value ##
856
+ $value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
857
+
858
+ // include the user's BP group in the export ##
859
+ }
860
+ elseif ( isset( $_POST['groups'] ) && $_POST['groups'] == '1' && $field == 'groups' )
861
+ {
862
+
863
+ if ( function_exists( 'groups_get_user_groups' ) ) {
864
+
865
+ // check if user is a member of any groups ##
866
+ $group_ids = groups_get_user_groups( $user->ID );
867
+
868
+ #self::pr( $group_ids );
869
+ #wp_die( pr( 'loaded group data.' ));
870
+
871
+ if ( ! $group_ids || $group_ids == '' ) {
872
+
873
+ $value = '';
874
+
875
+ } else {
876
+
877
+ // new empty array ##
878
+ $groups = array();
879
+
880
+ // loop over all groups ##
881
+ foreach( $group_ids["groups"] as $group_id ) {
882
+
883
+ $groups[] = groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
884
+
885
+ }
886
+
887
+ // implode it ##
888
+ $value = implode( $groups, '|' );
889
+
890
+ }
891
+
892
+ } else {
893
+
894
+ $value = '';
895
+
896
+ }
897
+
898
+ }
899
+ elseif ( $field == 'bp_latest_update' )
900
+ {
901
+
902
+ // https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
903
+ $value = bp_get_user_last_activity( $user->ID );
904
+
905
+ // user or usermeta field ##
906
+ }
907
+ else
908
+ {
909
+
910
+ // the user_meta key isset ##
911
+ if ( isset( $get_user_meta[$field] ) ) {
912
+
913
+ // take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
914
+ $value = $get_user_meta[$field][0];
915
+
916
+ // standard WP_User value ##
917
+ } else {
918
+
919
+ // use the magically assigned value from WP_Users
920
+ $value = $user->{$field};
921
+
922
+ }
923
+
924
+
925
+ // the $value might be serialized ##
926
+ $value = self::unserialize( $value );
927
+
928
+ // the value is an array ##
929
+ if ( is_array ( $value ) ) {
930
+
931
+ // recursive implode it ##
932
+ $value = self::recursive_implode( $value );
933
+
934
+ }
935
+
936
+ }
937
+
938
+
939
+ // correct program value to Program Name ##
940
+ if ( $field == 'member_of_club' ) {
941
+
942
+ $value = get_the_title($value);
943
+
944
+ }
945
+
946
+ // wrap values in quotes and add to array ##
947
+ if ( $is_csv ) {
948
+
949
+ $data[] = '"' . str_replace( '"', '""', $value ) . '"';
950
+
951
+ // just add to array ##
952
+ } else {
953
+
954
+ $data[] = $value;
955
+ }
956
+
957
+ }
958
+
959
+ // echo row data ##
960
+ echo $pre . implode( $seperator, $data ) . $breaker;
961
+
962
+ }
963
+
964
+ // close doc wrapper..
965
+ echo $doc_end;
966
+
967
+ // stop PHP, so file can export correctly ##
968
+ exit;
969
+
970
+ }
971
+
972
+
973
+ /**
974
+ * Content of the settings page
975
+ *
976
+ * @since 0.1
977
+ **/
978
+ public function users_page()
979
+ {
980
+
981
+ // quick security check ##
982
+ if ( ! current_user_can( 'list_users' ) ) {
983
+
984
+ wp_die( __( 'You do not have sufficient permissions to access this page.', 'export-user-data' ) );
985
+
986
+ }
987
+
988
+ // Save settings button was pressed ##
989
+ if (
990
+ isset( $_POST['save_export'] )
991
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
992
+ ) {
993
+
994
+ // start with an empty variable ##
995
+ $save_export = "";
996
+
997
+ if ( ! empty( $_POST['save_new_export_name'] ) ) {
998
+
999
+ // assign value ##
1000
+ $save_export = $_POST['save_new_export_name'];
1001
+
1002
+ } elseif ( ! empty( $_POST['export_name'] ) ) {
1003
+
1004
+ $save_export = $_POST['export_name'];
1005
+
1006
+ }
1007
+
1008
+ // clean up $save_export ##
1009
+ $save_export = sanitize_text_field( $save_export );
1010
+
1011
+ // Build array of $options to save and save them ##
1012
+ if ( isset( $save_export ) ) {
1013
+
1014
+ // prepare all array values ##
1015
+ $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
1016
+ $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
1017
+ $bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '' ;
1018
+ $format = isset( $_POST['format'] ) ? $_POST['format'] : '' ;
1019
+ $role = isset( $_POST['role'] ) ? $_POST['role'] : '' ;
1020
+ $roles = isset( $_POST['roles'] ) ? $_POST['roles'] : '0' ;
1021
+ $groups = isset( $_POST['groups'] ) ? $_POST['groups'] : '0' ;
1022
+ $start_date = isset( $_POST['start_date'] ) ? $_POST['start_date'] : '' ;
1023
+ $end_date = isset( $_POST['end_date'] ) ? $_POST['end_date'] : '' ;
1024
+ $limit_offset = isset( $_POST['limit_offset'] ) ? $_POST['limit_offset'] : '' ;
1025
+ $limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
1026
+ $updated_since_date = isset ( $_POST['updated_since_date'] ) ? $_POST['updated_since_date'] : '' ;
1027
+ $field_updated_since = isset ( $_POST['bp_field_updated_since'] ) ? $_POST['bp_field_updated_since'] : '';
1028
+
1029
+ // assign all values to an array ##
1030
+ $save_array = array (
1031
+ 'usermeta_saved_fields' => $usermeta,
1032
+ 'bp_fields_saved_fields' => $bp_fields,
1033
+ 'bp_fields_update_time_saved_fields' => $bp_fields_update,
1034
+ 'role' => $role,
1035
+ 'roles' => $roles,
1036
+ 'groups' => $groups,
1037
+ 'start_date' => $start_date,
1038
+ 'end_date' => $end_date,
1039
+ 'limit_offset' => $limit_offset,
1040
+ 'limit_total' => $limit_total,
1041
+ 'updated_since_date' => $updated_since_date,
1042
+ 'field_updated_since' => $field_updated_since,
1043
+ 'format' => $format
1044
+ );
1045
+
1046
+ // store the options, for next load ##
1047
+ $this->set_user_options( $save_export, $save_array );
1048
+
1049
+ // Display the settings the user just saved instead of blanking the form ##
1050
+ $_POST['load_export'] = 'Load Settings';
1051
+ $_POST['export_name'] = $save_export;
1052
+
1053
+ }
1054
+
1055
+ }
1056
+
1057
+ // Load settings button was pressed ( or option saved and $_POST variables hijacked )##
1058
+ if (
1059
+ isset( $_POST['load_export'] )
1060
+ && isset( $_POST['export_name'] )
1061
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1062
+ ) {
1063
+
1064
+ $this->get_user_options_by_export( sanitize_text_field( $_POST['export_name'] ) );
1065
+
1066
+ }
1067
+
1068
+ // Delete settings button was pressed ##
1069
+ if (
1070
+ isset( $_POST['delete_export'] )
1071
+ && isset( $_POST['export_name'] )
1072
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1073
+ ) {
1074
+
1075
+ $this->delete_user_options( sanitize_text_field( $_POST['export_name'] ) );
1076
+
1077
+ }
1078
+
1079
+ ?>
1080
+ <div class="wrap">
1081
+ <h2><?php _e( 'Export User Data', 'export-user-data' ); ?></h2>
1082
+ <?php
1083
+
1084
+ // nothing happening? ##
1085
+ if ( isset( $_GET['error'] ) ) {
1086
+ echo '<div class="updated"><p><strong>' . __( 'No users found.', 'export-user-data' ) . '</strong></p></div>';
1087
+ }
1088
+
1089
+ ?>
1090
+ <form method="post" action="" enctype="multipart/form-data">
1091
+ <?php wp_nonce_field( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' ); ?>
1092
+ <table class="form-table">
1093
+ <?php
1094
+
1095
+ // allow admin to select user meta fields to export ##
1096
+ global $wpdb;
1097
+ $meta_keys = $wpdb->get_results( "SELECT distinct(meta_key) FROM $wpdb->usermeta" );
1098
+
1099
+ // get meta_key value from object ##
1100
+ $meta_keys = wp_list_pluck( $meta_keys, 'meta_key' );
1101
+
1102
+ // let's note some of them odd keys ##
1103
+ $meta_keys_system = array(
1104
+ 'metaboxhidden',
1105
+ 'activation',
1106
+ 'bp_',
1107
+ 'nav_',
1108
+ 'wp_',
1109
+ 'admin_color',
1110
+ 'wpmudev',
1111
+ 'screen_',
1112
+ 'show_',
1113
+ 'rich_',
1114
+ 'reward_',
1115
+ 'meta-box',
1116
+ 'manageedit',
1117
+ 'edit_',
1118
+ 'closedpostboxes_',
1119
+ 'dismissed_',
1120
+ 'manage',
1121
+ 'comment',
1122
+ 'current',
1123
+ 'incentive_',
1124
+ '_wdp',
1125
+ 'ssl',
1126
+ 'wdfb',
1127
+ 'users_per_page',
1128
+ );
1129
+
1130
+ // allow array to be filtered ##
1131
+ $meta_keys_system = apply_filters( 'export_user_data_meta_keys_system', $meta_keys_system );
1132
+
1133
+ // test array ##
1134
+ #echo '<pre>'; var_dump($meta_keys); echo '</pre>';
1135
+
1136
+ // check if we got anything ? ##
1137
+ if ( $meta_keys ) {
1138
+
1139
+ ?>
1140
+ <tr valign="top">
1141
+ <th scope="row">
1142
+ <label for="q_eud_usermeta"><?php _e( 'User Meta Fields', 'export-user-data' ); ?></label>
1143
+ <p class="filter" style="margin: 10px 0 0;">
1144
+ <?php _e('Filter', 'export-user-data'); ?>: <a href="#" class="usermeta-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="usermeta-common"><?php _e('Common', 'export-user-data'); ?></a>
1145
+ </p>
1146
+ <p class="filter" style="margin: 10px 0 0;">
1147
+ <?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
1148
+ </p>
1149
+ </th>
1150
+ <td>
1151
+ <select multiple="multiple" id="usermeta" name="usermeta[]">
1152
+ <?php
1153
+
1154
+ foreach ( $meta_keys as $key ) {
1155
+
1156
+ #echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1157
+
1158
+ // display $key ##
1159
+ $display_key = $key;
1160
+
1161
+ // rename programs field ##
1162
+ if ( $display_key == 'member_of_club' ){
1163
+ $display_key = 'program';
1164
+ }
1165
+
1166
+ // tidy ##
1167
+ $display_key = str_replace( "_", " ", ucwords( $display_key ) );
1168
+
1169
+ #echo "<label for='".esc_attr( $key )."' title='".esc_attr( $key )."'><input id='".esc_attr( $key )."' type='checkbox' name='usermeta[]' value='".esc_attr( $key )."'/> $display_key</label><br />";
1170
+
1171
+ // class ##
1172
+ $usermeta_class = 'normal';
1173
+
1174
+ foreach ( $meta_keys_system as $drop ) {
1175
+
1176
+ if ( strpos( $key, $drop ) !== false ) {
1177
+
1178
+ // https://wordpress.org/support/topic/bugfix-numbers-in-export-headers?replies=1
1179
+ // removed $key = assignment, as not required ##
1180
+ if ( ( array_search( $key, $meta_keys ) ) !== false ) {
1181
+
1182
+ $usermeta_class = 'system';
1183
+
1184
+ }
1185
+
1186
+ }
1187
+
1188
+ }
1189
+
1190
+ // print key ##
1191
+ echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."' class='".$usermeta_class."'>$display_key</option>";
1192
+
1193
+ }
1194
+ ?>
1195
+ </select>
1196
+ <p class="description"><?php
1197
+ printf(
1198
+ __( 'Select the user meta keys to export, use the filters to simplify the list.', 'export-user-data' )
1199
+ );
1200
+ ?></p>
1201
+ </td>
1202
+ </tr>
1203
+ <?php
1204
+
1205
+ } // meta_keys found ##
1206
+
1207
+ ?>
1208
+ <?php
1209
+
1210
+ // buddypress x profile data ##
1211
+ if ( function_exists ('bp_is_active') ) {
1212
+
1213
+ // grab all buddypress x profile fields ##
1214
+ $bp_fields = $wpdb->get_results( "SELECT distinct(name) FROM ".$wpdb->base_prefix."bp_xprofile_fields WHERE parent_id = 0" );
1215
+
1216
+ // get name value from object ##
1217
+ $bp_fields = wp_list_pluck( $bp_fields, 'name' );
1218
+
1219
+ // test array ##
1220
+ #echo '<pre>'; var_dump($bp_fields); echo '</pre>';
1221
+
1222
+ // allow array to be filtered ##
1223
+ $bp_fields = apply_filters( 'export_user_data_bp_fields', $bp_fields );
1224
+
1225
+ ?>
1226
+ <tr valign="top">
1227
+ <th scope="row">
1228
+ <label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields', 'export-user-data' ); ?></label>
1229
+ <p class="filter" style="margin: 10px 0 0;">
1230
+ <?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
1231
+ </p>
1232
+ </th>
1233
+ <td>
1234
+ <select multiple="multiple" id="bp_fields" name="bp_fields[]">
1235
+ <?php
1236
+
1237
+ foreach ( $bp_fields as $key ) {
1238
+
1239
+ // tidy up key ##
1240
+ $key_tidy = str_replace( ' ', '__', ($key));
1241
+
1242
+ #echo "<label for='".esc_attr( $key_tidy )."'><input id='".esc_attr( $key_tidy )."' type='checkbox' name='bp_fields[]' value='".esc_attr( $key_tidy )."'/> $key</label><br />";
1243
+
1244
+ // print key ##
1245
+ echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
1246
+
1247
+ }
1248
+
1249
+ ?>
1250
+ </select>
1251
+ <p class="description"><?php
1252
+ printf(
1253
+ __( 'Select the BuddyPress XProfile keys to export', 'export-user-data' )
1254
+ );
1255
+ ?></p>
1256
+ </td>
1257
+ </tr>
1258
+ <?php
1259
+
1260
+ // allow export of update times ##
1261
+
1262
+ ?>
1263
+ <tr valign="top" class="toggleable">
1264
+ <th scope="row">
1265
+ <label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields Update Time', 'export-user-data' ); ?></label>
1266
+ <p class="filter" style="margin: 10px 0 0;">
1267
+ <?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
1268
+ </p>
1269
+ </th>
1270
+ <td>
1271
+ <select multiple="multiple" id="bp_fields_update_time" name="bp_fields_update_time[]">
1272
+ <?php
1273
+
1274
+ foreach ( $bp_fields as $key ) {
1275
+
1276
+ echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
1277
+
1278
+ }
1279
+
1280
+ ?>
1281
+ </select>
1282
+ <p class="description"><?php
1283
+ printf(
1284
+ __( 'Select the BuddyPress XProfile keys updated dates to export', 'export-user-data' )
1285
+ );
1286
+ ?></p>
1287
+ </td>
1288
+ </tr>
1289
+
1290
+ <tr valign="top" class="toggleable">
1291
+ <th scope="row"><label for="groups"><?php _e( 'BP User Groups', 'export-user-data' ); ?></label></th>
1292
+ <td>
1293
+ <input id='groups' type='checkbox' name='groups' value='1' <?php checked( isset ( $this->groups ) ? intval ( $this->groups ) : '', 1 ); ?> />
1294
+ <p class="description"><?php
1295
+ printf(
1296
+ __( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1297
+ , esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
1298
+ , 'Codex'
1299
+ );
1300
+ ?></p>
1301
+ </td>
1302
+ </tr>
1303
+ <?php
1304
+
1305
+ } // BP installed and active ##
1306
+
1307
+ ?>
1308
+ <tr valign="top" class="toggleable">
1309
+ <th scope="row"><label for="q_eud_users_role"><?php _e( 'Role', 'export-user-data' ); ?></label></th>
1310
+ <td>
1311
+ <select name="role" id="q_eud_users_role">
1312
+ <?php
1313
+
1314
+ echo '<option value="">' . __( 'All Roles', 'export-user-data' ) . '</option>';
1315
+ global $wp_roles;
1316
+
1317
+ foreach ( $wp_roles->role_names as $role => $name ) {
1318
+
1319
+ if ( isset ( $this->role ) && ( $this->role == $role ) ) {
1320
+
1321
+ echo "\n\t<option selected value='" . esc_attr( $role ) . "'>$name</option>";
1322
+
1323
+ } else {
1324
+
1325
+ echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1326
+
1327
+ }
1328
+ }
1329
+
1330
+
1331
+ ?>
1332
+ </select>
1333
+ <p class="description"><?php
1334
+ printf(
1335
+ __( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1336
+ , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1337
+ , 'Codex'
1338
+ );
1339
+ ?></p>
1340
+ </td>
1341
+ </tr>
1342
+
1343
+ <tr valign="top" class="toggleable">
1344
+ <th scope="row"><label for="roles"><?php _e( 'User Roles', 'export-user-data' ); ?></label></th>
1345
+ <td>
1346
+ <input id='roles' type='checkbox' name='roles' value='1' <?php checked( isset ( $this->roles ) ? intval ( $this->roles ) : '', 1 ); ?> />
1347
+ <p class="description"><?php
1348
+ printf(
1349
+ __( 'Include all of the users <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1350
+ , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1351
+ , 'Roles'
1352
+ );
1353
+ ?></p>
1354
+ </td>
1355
+ </tr>
1356
+ <?php
1357
+
1358
+ // clubs ? ##
1359
+ if ( post_type_exists( 'club' ) ) {
1360
+
1361
+ ?>
1362
+ <tr valign="top" class="toggleable">
1363
+ <th scope="row"><label for="q_eud_users_program"><?php _e( 'Programs', 'export-user-data' ); ?></label></th>
1364
+ <td>
1365
+ <select name="program" id="q_eud_users_program">
1366
+ <?php
1367
+
1368
+ echo '<option value="">' . __( 'All Programs', 'export-user-data' ) . '</option>';
1369
+
1370
+ $clubs_array = get_posts(array( 'post_type'=> 'club', 'posts_per_page' => -1 )); // grab all posts of type "club" ##
1371
+
1372
+ foreach ( $clubs_array as $c ) { // loop over all clubs ##
1373
+
1374
+ #$clubs[$c->ID] = $c; // grab club ID ##
1375
+ echo "\n\t<option value='" . esc_attr( $c->ID ) . "'>$c->post_title</option>";
1376
+
1377
+ }
1378
+
1379
+ ?>
1380
+ </select>
1381
+ </td>
1382
+ </tr>
1383
+ <?php
1384
+
1385
+ } // clubs ##
1386
+
1387
+ ?>
1388
+ <tr valign="top" class="toggleable">
1389
+ <th scope="row"><label><?php _e( 'Registered', 'export-user-data' ); ?></label></th>
1390
+ <td>
1391
+ <input type="text" id="q_eud_users_start_date" name="start_date" value="<?php echo $this->start_date; ?>" class="start-datepicker" />
1392
+ <input type="text" id="q_eud_users_end_date" name="end_date" value="<?php echo $this->end_date; ?>" class="end-datepicker" />
1393
+ <p class="description"><?php
1394
+ printf(
1395
+ __( 'Pick a start and end user registration date to limit the results.', 'export-user-data' )
1396
+ );
1397
+ ?></p>
1398
+ </td>
1399
+ </tr>
1400
+
1401
+ <tr valign="top" class="toggleable">
1402
+ <th scope="row"><label><?php _e( 'Limit Range', 'export-user-data' ); ?></label></th>
1403
+ <td>
1404
+ <input name="limit_offset" type="text" id="q_eud_users_limit_offset" value="<?php echo( $this->limit_offset ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Offset', 'export-user-data' ); ?>">
1405
+ <input name="limit_total" type="text" id="q_eud_users_limit_total" value="<?php echo ( $this->limit_total ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Total', 'export-user-data' ); ?>">
1406
+ <p class="description"><?php
1407
+ printf(
1408
+ __( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1409
+ , esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
1410
+ , 'Codex'
1411
+ );
1412
+ ?></p>
1413
+ </td>
1414
+ </tr>
1415
+
1416
+ <tr valign="top" class="toggleable">
1417
+ <th scope="row"><label><?php _e( 'Updated Since', 'export-user-data' ); ?></label></th>
1418
+ <td>
1419
+ <input type="text" id="q_eud_updated_since_date" name="updated_since_date" value="<?php echo $this->updated_since_date; ?>" class="updated-datepicker" />
1420
+ <select id="bp_field_updated_since" name="bp_field_updated_since">
1421
+ <?php
1422
+
1423
+ foreach ( $bp_fields as $key ) {
1424
+ if ( $this->field_updated_since == $key ) {
1425
+ echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."' selected>$key</option>";
1426
+ } else {
1427
+ echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
1428
+ }
1429
+ }
1430
+
1431
+ ?>
1432
+ </select>
1433
+
1434
+ <p class="description"><?php
1435
+ printf(
1436
+ __( 'Limit the results to users who have updated this extended profile field after this date.', 'export-user-data' )
1437
+ );
1438
+ ?></p>
1439
+ </td>
1440
+ </tr>
1441
+
1442
+ <tr valign="top">
1443
+ <th scope="row"><label for="q_eud_users_format"><?php _e( 'Format', 'export-user-data' ); ?></label></th>
1444
+ <td>
1445
+ <select name="format" id="q_eud_users_format">
1446
+ <?php
1447
+ if ( isset ( $this->format ) && ( $this->format == 'excel' ) ) {
1448
+ echo '<option selected value="excel">' . __( 'Excel', 'export-user-data' ) . '</option>';
1449
+ } else {
1450
+ echo '<option value="excel">' . __( 'Excel', 'export-user-data' ) . '</option>';
1451
+ }
1452
+ if ( isset ( $this->format ) && ( $this->format == 'csv' ) ) {
1453
+ echo '<option selected value="csv">' . __( 'CSV', 'export-user-data' ) . '</option>';
1454
+ } else {
1455
+ echo '<option value="csv">' . __( 'CSV', 'export-user-data' ) . '</option>';
1456
+ }
1457
+ ?>
1458
+ </select>
1459
+ <p class="description"><?php
1460
+ printf(
1461
+ __( 'Select the format for the export file.', 'export-user-data' )
1462
+ );
1463
+ ?></p>
1464
+ </td>
1465
+ </tr>
1466
+
1467
+ <tr valign="top" class="remember">
1468
+ <th scope="row"><label for="q_eud_save_options"><?php _e( 'Stored Options', 'export-user-data' ); ?></label></th>
1469
+ <td>
1470
+
1471
+ <div class="row">
1472
+ <input type="text" class="regular-text" name="save_new_export_name" id="q_eud_save_options_new_export" placeholder="<?php _e( 'Export Name', 'export-user-data' ); ?>" value="<?php echo isset( $_POST['export_name'] ) ? $_POST['export_name'] : '' ; ?>">
1473
+ <input type="submit" id="save_export" class="button-primary" name="save_export" value="<?php _e( 'Save', 'export-user-data' ); ?>" />
1474
+ </div>
1475
+ <?php
1476
+
1477
+ // check if the user has any saved exports ##
1478
+ if ( $this->get_user_options() ) {
1479
+
1480
+ ?>
1481
+ <div class="row">
1482
+ <select name="export_name" id="q_eud_save_options" class="regular-text">
1483
+ <?php
1484
+
1485
+ // loop over each saved export ##
1486
+ foreach( $this->get_user_options() as $export ) {
1487
+
1488
+ // select Loaded export name, if selected ##
1489
+ if (
1490
+ isset( $_POST['load_export'] )
1491
+ && isset( $_POST['export_name'] )
1492
+ && ( $_POST['export_name'] == $export )
1493
+ ) {
1494
+
1495
+ echo "<option selected value='$export'>$export</option>";
1496
+
1497
+ // just list previous export name ##
1498
+ } else {
1499
+
1500
+ echo "<option value='$export'>$export</option>";
1501
+
1502
+ }
1503
+
1504
+ }
1505
+
1506
+ ?>
1507
+ </select>
1508
+
1509
+ <input type="submit" id="load_export" class="button-primary" name="load_export" value="<?php _e( 'Load', 'export-user-data' ); ?>" />
1510
+ <input type="submit" id="delete_export" class="button-primary" name="delete_export" value="<?php _e( 'Delete', 'export-user-data' ); ?>" />
1511
+ <?php
1512
+
1513
+ }
1514
+
1515
+ ?>
1516
+ </div>
1517
+ <p class="description"><?php _e( 'Save, load or delete your stored export options.', 'export-user-data' ); ?></p>
1518
+
1519
+ </td>
1520
+ </tr>
1521
+
1522
+ <tr valign="top">
1523
+ <th scope="row">
1524
+ <label for="q_eud_xprofile"><?php _e( 'Advanced Options', 'export-user-data' ); ?></label>
1525
+ </th>
1526
+ <td>
1527
+ <div class="toggle">
1528
+ <a href="#"><?php _e( 'Show', 'export-user-data' ); ?></a>
1529
+ </div>
1530
+ </td>
1531
+ </tr>
1532
+
1533
+ </table>
1534
+ <p class="submit">
1535
+ <input type="hidden" name="_wp_http_referer" value="<?php echo $_SERVER['REQUEST_URI'] ?>" />
1536
+ <input type="submit" class="button-primary" value="<?php _e( 'Run Export', 'export-user-data' ); ?>" />
1537
+ </p>
1538
+ </form>
1539
+ </div>
1540
+
1541
+ <?php
1542
+ }
1543
+
1544
+
1545
+ /**
1546
+ * Inline jQuery
1547
+ * @since 0.8.2
1548
+ */
1549
+ public function jquery()
1550
+ {
1551
+
1552
+ // load the scripts on only the plugin admin page
1553
+ if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
1554
+ ?>
1555
+ <script>
1556
+
1557
+ // lazy load in some jQuery validation ##
1558
+ jQuery(document).ready(function($) {
1559
+
1560
+ // build super multiselect ##
1561
+ jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
1562
+
1563
+ //Select any fields from saved settings ##
1564
+ jQuery('#usermeta').multiSelect('select',([<?php echo( self::quote_array( $this->usermeta_saved_fields ) ); ?>]));
1565
+ jQuery('#bp_fields').multiSelect('select',([<?php echo( self::quote_array($this->bp_fields_saved_fields ) ); ?>]));
1566
+ jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( self::quote_array( $this->bp_fields_update_time_saved_fields ) ); ?>]));
1567
+
1568
+ // show only common ##
1569
+ jQuery('.usermeta-common').click(function(e){
1570
+ e.preventDefault();
1571
+ jQuery('#ms-usermeta .ms-selectable li.system').hide();
1572
+ });
1573
+
1574
+ // show all ##
1575
+ jQuery('.usermeta-all').click(function(e){
1576
+ e.preventDefault();
1577
+ jQuery('#ms-usermeta .ms-selectable li').show();
1578
+ });
1579
+
1580
+ // select all ##
1581
+ jQuery('.select-all').click(function(e){
1582
+ e.preventDefault();
1583
+ jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
1584
+ });
1585
+
1586
+ // select none ##
1587
+ jQuery('.select-none').click(function(e){
1588
+ e.preventDefault();
1589
+ jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'deselect_all' );
1590
+ });
1591
+
1592
+
1593
+ // validate number inputs ##
1594
+ $("input.numeric").blur(function() {
1595
+
1596
+ //console.log("you entered "+ $(this).val());
1597
+
1598
+ if ( $(this).val() && ! $.isNumeric( $(this).val() ) ) {
1599
+
1600
+ //console.log("this IS NOT a number");
1601
+ $(this).css({ 'background': 'red', 'color': 'white' }); // highlight error ##
1602
+ $("p.submit .button-primary").attr('disabled','disabled'); // disable submit ##
1603
+
1604
+ } else {
1605
+
1606
+ $(this).css({ 'background': 'white', 'color': '#333' }); // remove error highlighting ##
1607
+ $("p.submit .button-primary").removeAttr('disabled'); // enable submit ##
1608
+
1609
+ }
1610
+
1611
+ });
1612
+
1613
+ // toggle advanced options ##
1614
+ jQuery(".toggle a").click( function(e) {
1615
+ e.preventDefault();
1616
+ $toggleable = jQuery("tr.toggleable");
1617
+ $toggleable.toggle();
1618
+ if ( $toggleable.is(":visible") ) {
1619
+ jQuery(this).text("<?php _e( 'Hide', 'export-user-data' ); ?>");
1620
+ } else {
1621
+ jQuery(this).text("<?php _e( 'Show', 'export-user-data' ); ?>");
1622
+ }
1623
+ });
1624
+
1625
+ // validate save button ##
1626
+ jQuery("#save_export").click( function(e) {
1627
+
1628
+ // grab the value of the input ##
1629
+ var q_eud_save_options_new_export = jQuery('#q_eud_save_options_new_export').val();
1630
+
1631
+ if ( ! q_eud_save_options_new_export || q_eud_save_options_new_export == '' ) {
1632
+
1633
+ e.preventDefault(); // stop things here ##
1634
+ jQuery('#q_eud_save_options_new_export').addClass("error");
1635
+
1636
+ }
1637
+
1638
+ });
1639
+
1640
+ // remove validation on focus ##
1641
+ jQuery("body").on( 'focus', '#q_eud_save_options_new_export', function(e) {
1642
+
1643
+ jQuery(this).removeClass("error");
1644
+
1645
+ });
1646
+
1647
+ <?php
1648
+
1649
+ // method returns an object with "first" & "last" keys ##
1650
+ $dates = self::get_user_registered_dates();
1651
+
1652
+ ?>
1653
+
1654
+ // start date picker ##
1655
+ jQuery('.start-datepicker').datepicker( {
1656
+ dateFormat : 'yy-mm-dd',
1657
+ minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1658
+ maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
1659
+ } );
1660
+
1661
+ // end date picker ##
1662
+ jQuery('.end-datepicker').datepicker( {
1663
+ dateFormat : 'yy-mm-dd',
1664
+ minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1665
+ maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
1666
+ } );
1667
+
1668
+ // end date picker ##
1669
+ // might want to set minDate to something else, but not sure
1670
+ // what would be best for everyone
1671
+ jQuery('.updated-datepicker').datepicker( {
1672
+ dateFormat : 'yy-mm-dd',
1673
+ minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1674
+ maxDate : '0'
1675
+ } );
1676
+
1677
+ });
1678
+
1679
+ </script>
1680
+ <?php
1681
+ }
1682
+
1683
+ }
1684
+
1685
+
1686
+ /**
1687
+ * Inline CSS
1688
+ * @since 0.8.2
1689
+ */
1690
+ public function css()
1691
+ {
1692
+
1693
+ // load the scripts on only the plugin admin page
1694
+ if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
1695
+ ?>
1696
+ <style>
1697
+ .toggleable { display: none; }
1698
+ .hidden { display: none; }
1699
+ </style>
1700
+ <?php
1701
+ }
1702
+
1703
+ }
1704
+
1705
+
1706
+ /**
1707
+ * Data to exclude from export
1708
+ */
1709
+ public function get_exclude_fields()
1710
+ {
1711
+
1712
+ $exclude_fields = array (
1713
+ 'user_pass'
1714
+ #, 'user_activation_key'
1715
+ );
1716
+
1717
+ return apply_filters( 'export_user_data_exclude_fields', $exclude_fields );
1718
+
1719
+ }
1720
+
1721
+
1722
+ /**
1723
+ * Get the array of standard WP_User fields to return
1724
+ */
1725
+ public function get_user_fields()
1726
+ {
1727
+
1728
+ // exportable user data ##
1729
+ $user_fields = array(
1730
+ 'ID'
1731
+ , 'user_login'
1732
+ #, 'user_pass'
1733
+ , 'user_nicename'
1734
+ , 'user_email'
1735
+ , 'user_url'
1736
+ , 'user_registered'
1737
+ #, 'user_activation_key'
1738
+ , 'user_status'
1739
+ , 'display_name'
1740
+ );
1741
+
1742
+ return apply_filters( 'export_user_data_user_fields', $user_fields );
1743
+
1744
+ }
1745
+
1746
+
1747
+ /**
1748
+ * Get the array of special user fields to return
1749
+ */
1750
+ public function get_special_fields()
1751
+ {
1752
+
1753
+ // exportable user data ##
1754
+ $special_fields = array(
1755
+ 'roles' // list of WP Roles
1756
+ , 'groups' // BP Groups
1757
+ );
1758
+
1759
+ return apply_filters( 'export_user_data_special_fields', $special_fields );
1760
+
1761
+ }
1762
+
1763
+
1764
+ /*
1765
+ * Pre User Query
1766
+ */
1767
+ public function pre_user_query( $user_search )
1768
+ {
1769
+
1770
+ global $wpdb;
1771
+
1772
+ $where = '';
1773
+
1774
+ if ( ! empty( $_POST['start_date'] ) ) {
1775
+
1776
+ $date = new DateTime( sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
1777
+ $date_formatted = $date->format( 'Y-m-d H:i:s' );
1778
+
1779
+ $where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
1780
+
1781
+ }
1782
+ if ( ! empty( $_POST['end_date'] ) ) {
1783
+
1784
+ $date = new DateTime( sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
1785
+ $date_formatted = $date->format( 'Y-m-d H:i:s' );
1786
+
1787
+ $where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
1788
+
1789
+ }
1790
+
1791
+ //search by last update time of BP extended fields
1792
+ if ( ( isset ($_POST['updated_since_date'] ) && $_POST['updated_since_date'] != '' ) &&
1793
+ (isset ($_POST['bp_field_updated_since'] ) && $_POST['bp_field_updated_since'] != '' ) ) {
1794
+ $last_updated_date = new DateTime( sanitize_text_field ( $_POST['updated_since_date'] ) . ' 00:00:00' );
1795
+ $this->updated_since_date = $last_updated_date->format( 'Y-m-d H:i:s' );
1796
+ $this->field_updated_since = sanitize_text_field ( $_POST['bp_field_updated_since'] );
1797
+ $field_updated_since_id = BP_Xprofile_Field::get_id_from_name( $this->field_updated_since );
1798
+ $user_search->query_from .= " JOIN `wp_bp_xprofile_data` XP ON XP.user_id = wp_users.ID ";
1799
+ $where .= $wpdb->prepare( " AND XP.field_id = %s AND XP.last_updated >= %s", $field_updated_since_id, $this->updated_since_date );
1800
+ }
1801
+
1802
+ if ( ! empty( $where ) ) {
1803
+
1804
+ $user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
1805
+
1806
+ }
1807
+
1808
+ #wp_die( self::pr( $user_search ) );
1809
+ return $user_search;
1810
+
1811
+ }
1812
+
1813
+
1814
+ /**
1815
+ * Export Date Options
1816
+ *
1817
+ * @since 0.9.6
1818
+ * @global type $wpdb
1819
+ * @return Array of objects
1820
+ */
1821
+ private static function get_user_registered_dates()
1822
+ {
1823
+
1824
+ // invite in global objects ##
1825
+ global $wpdb;
1826
+
1827
+ // query user table for oldest and newest registration ##
1828
+ $range =
1829
+ $wpdb->get_results (
1830
+ #$wpdb->prepare (
1831
+ "
1832
+ SELECT
1833
+ MIN( user_registered ) AS first,
1834
+ MAX( user_registered ) AS last
1835
+ FROM
1836
+ {$wpdb->users}
1837
+ "
1838
+ #)
1839
+ );
1840
+
1841
+ return $range;
1842
+
1843
+ /*
1844
+ // invite in global objects ##
1845
+ global $wpdb, $wp_locale;
1846
+
1847
+ // grab list of years and months available
1848
+ $months = $wpdb->get_results( "
1849
+ SELECT DISTINCT YEAR( user_registered ) AS year, MONTH( user_registered ) AS month, DAY( user_registered ) AS day
1850
+ FROM $wpdb->users
1851
+ ORDER BY user_registered DESC
1852
+ " );
1853
+
1854
+ // check if we got a result ##
1855
+ $month_count = count( $months );
1856
+
1857
+ // nothing cokking ##
1858
+ if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
1859
+
1860
+ return;
1861
+
1862
+ }
1863
+
1864
+ #wp_die( self::pr( $months ) );
1865
+
1866
+ // loop over each month ##
1867
+ foreach ( $months as $date ) {
1868
+
1869
+ // skip if year == '0' ##
1870
+ if ( 0 == $date->year ) {
1871
+ continue;
1872
+ }
1873
+
1874
+ // make sure the month is in a MM two digit format ##
1875
+ $month = zeroise( $date->month, 2 );
1876
+
1877
+ // build up a tae string - YYYY-MM ##
1878
+ $date_string = $date->year . '-' . $month;
1879
+
1880
+ // check if passed date matches this string ##
1881
+ if ( $selected_date == $date_string ) {
1882
+
1883
+ ?>
1884
+ <option selected value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1885
+ <?php
1886
+
1887
+ } else {
1888
+
1889
+ ?>
1890
+ <option value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1891
+ <?php
1892
+
1893
+ }
1894
+
1895
+ }
1896
+ */
1897
+
1898
+ }
1899
+
1900
+
1901
+ /**
1902
+ * Quote array elements and separate with commas
1903
+ *
1904
+ * @since 0.9.6
1905
+ * @return String
1906
+ */
1907
+ private static function quote_array( $array )
1908
+ {
1909
+
1910
+ $prefix = ''; // starts empty ##
1911
+ $elementlist = '';
1912
+ if ( is_array( $array ) ) {
1913
+ foreach( $array as $element ) {
1914
+ $elementlist .= $prefix . "'" . $element . "'";
1915
+ $prefix = ','; // prefix all remaining items with a comma ##
1916
+ }
1917
+ }
1918
+
1919
+ // kick back string to function caller ##
1920
+ return( $elementlist );
1921
+
1922
+ }
1923
+
1924
+
1925
+ /**
1926
+ * Recursively implodes an array
1927
+ *
1928
+ * @since 1.0.1
1929
+ * @access public
1930
+ * @param array $array multi-dimensional array to recursively implode
1931
+ * @param string $glue value that glues elements together
1932
+ * @param bool $include_keys include keys before their values
1933
+ * @param bool $trim_all trim ALL whitespace from string
1934
+ * @return string imploded array
1935
+ */
1936
+ public static function recursive_implode( $array, $return = null, $glue = '|' )
1937
+ {
1938
+
1939
+ // unserialize ##
1940
+ $array = self::unserialize( $array );
1941
+
1942
+ // kick it back ##
1943
+ if ( is_null ( $return ) && ! is_array( $array ) ) {
1944
+
1945
+ return $array;
1946
+
1947
+ }
1948
+
1949
+ // empty return ##
1950
+ if ( is_null ( $return ) ) {
1951
+
1952
+ $return = '';
1953
+
1954
+ } else {
1955
+
1956
+ if ( "||" == $glue ) {
1957
+
1958
+ $glue = '|||';
1959
+
1960
+ } else if ( "|" == $glue ) {
1961
+
1962
+ $glue = '||';
1963
+
1964
+ }
1965
+
1966
+ }
1967
+
1968
+ // loop ##
1969
+ foreach( $array as $key => $value ) {
1970
+
1971
+ // unserialize ##
1972
+ $value = self::unserialize( $value );
1973
+
1974
+ if( is_array( $value ) ) {
1975
+
1976
+ $return .= $glue . $key . $glue . self::recursive_implode( $value, $return, $glue );
1977
+
1978
+ } else {
1979
+
1980
+ $return .= $glue . $key . $glue . $value;
1981
+
1982
+ }
1983
+
1984
+ }
1985
+
1986
+ // Removes first $glue from string ##
1987
+ if ( $glue && $return && $return[0] == '|' ) {
1988
+
1989
+ $return = ltrim ( $return, '|' );
1990
+
1991
+ }
1992
+
1993
+ // Trim ALL whitespace ##
1994
+ if ( $return ) {
1995
+
1996
+ $return = preg_replace( "/(\s)/ixsm", '', $return );
1997
+
1998
+ }
1999
+
2000
+ // kick it back ##
2001
+ return $return;
2002
+
2003
+ }
2004
+
2005
+
2006
+ /**
2007
+ * Save Unserializer
2008
+ *
2009
+ * @since 1.1.4
2010
+ */
2011
+ public static function unserialize( $value )
2012
+ {
2013
+
2014
+ // the $value is serialized ##
2015
+ if ( is_serialized( $value ) ) {
2016
+
2017
+ // unserliaze to new variable ##
2018
+ $unserialized = @unserialize( $value );
2019
+
2020
+ // test if unserliazing produced errors ##
2021
+ if ( $unserialized !== false || $value == 'b:0;' ) {
2022
+
2023
+ #$value = 'UNSERIALIZED_'.$unserialized;
2024
+ $value = $unserialized;
2025
+
2026
+ } else {
2027
+
2028
+ // failed to unserialize - data potentially corrupted in db ##
2029
+ #$value = 'NOT_SERIALIZED_'.$value;
2030
+ $value = $value;
2031
+
2032
+ }
2033
+
2034
+ }
2035
+
2036
+ // kick it back ##
2037
+ return $value;
2038
+
2039
+ }
2040
+
2041
+
2042
+ /**
2043
+ * Nicer var_dump
2044
+ *
2045
+ * @since 0.9.6
2046
+ */
2047
+ public static function pr ( $variable )
2048
+ {
2049
+
2050
+ echo '<pre>';
2051
+ print_r ( $variable );
2052
+ echo '</pre>';
2053
+
2054
+ }
2055
+
2056
+
2057
+ }
2058
+
2059
+ }
languages/export-user-data-el.mo ADDED
Binary file
languages/export-user-data-el.po ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Export User Data\n"
4
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/export-users-to-csv\n"
5
+ "POT-Creation-Date: 2014-03-15 09:46-0000\n"
6
+ "PO-Revision-Date: 2015-05-26 16:27+0200\n"
7
+ "Last-Translator: Ray <ray@qstudio.us>\n"
8
+ "Language-Team: Q Studio <team@qstudio.us>\n"
9
+ "Language: en\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 1.7.5\n"
14
+ "X-Poedit-KeywordsList: _;_e;_n;__\n"
15
+ "X-Poedit-Basepath: .\n"
16
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+ "X-Poedit-SearchPath-1: ..\n"
20
+
21
+ #: ../export-user-data.php:85 ../export-user-data.php:450
22
+ msgid "Export User Data"
23
+ msgstr "Εξαγωγή Δεδομένων Χρήστη"
24
+
25
+ #: ../export-user-data.php:445
26
+ msgid "You do not have sufficient permissions to access this page."
27
+ msgstr "Δεν έχετε επαρκή δικαιώματα για πρόσβαση στη σελίδα."
28
+
29
+ #: ../export-user-data.php:455
30
+ msgid "No users found."
31
+ msgstr "Δεν βρέθηκαν χρήστες"
32
+
33
+ #: ../export-user-data.php:511
34
+ msgid "User Meta Fields"
35
+ msgstr "Meta Πεδία Χρήστη"
36
+
37
+ #: ../export-user-data.php:513
38
+ msgid "Filter"
39
+ msgstr "Φίλτράρισμα"
40
+
41
+ #: ../export-user-data.php:513
42
+ msgid "All"
43
+ msgstr "Όλα"
44
+
45
+ #: ../export-user-data.php:513
46
+ msgid "Common"
47
+ msgstr "Κοινά"
48
+
49
+ #: ../export-user-data.php:564
50
+ msgid ""
51
+ "Select the user meta keys to export, use the filters to simplify the list."
52
+ msgstr ""
53
+ "Επιλέξτε τα meta κλειδιά του χρήστη προς εξαγωγή, χρησιμοποιήστε το "
54
+ "φιλτράρισμα για να απλοποιήσετε τη λίστα."
55
+
56
+ #: ../export-user-data.php:593
57
+ msgid "BP xProfile Fields"
58
+ msgstr "BP xProfile Πεδία"
59
+
60
+ #: ../export-user-data.php:614
61
+ msgid "Select the BuddyPress XProfile keys to export"
62
+ msgstr "Επιλέξτε τα BuddyPress XProfile κλειδιά προς εξαγωγή."
63
+
64
+ #: ../export-user-data.php:626
65
+ msgid "BP xProfile Fields Update Time"
66
+ msgstr "Ενημέρωση ώρας BP xProfile Πεδίων"
67
+
68
+ #: ../export-user-data.php:642
69
+ msgid "Select the BuddyPress XProfile keys updated dates to export"
70
+ msgstr ""
71
+ "Επιλέξτε τις ημερομηνίες ενημέρωσης των BuddyPress XProfile κλειδιών προς "
72
+ "εξαγωγή."
73
+
74
+ #: ../export-user-data.php:653
75
+ msgid "Role"
76
+ msgstr "Ρόλοι"
77
+
78
+ #: ../export-user-data.php:658
79
+ msgid "All Roles"
80
+ msgstr "Όλοι οι Ρόλοι"
81
+
82
+ #: ../export-user-data.php:668
83
+ #, php-format
84
+ msgid ""
85
+ "Filter the exported users by a WordPress Role. <a href=\"%s\" target=\"_blank"
86
+ "\">%s</a>"
87
+ msgstr ""
88
+ "Φιλτράρετε τους χρήστες προς εξαγωγή ως προς το Wordpress ρόλο τους. <a href="
89
+ "\"%s\" target=\"_blank\">%s</a>"
90
+
91
+ #: ../export-user-data.php:682
92
+ msgid "Programs"
93
+ msgstr "Προγράμματα"
94
+
95
+ #: ../export-user-data.php:687
96
+ msgid "All Programs"
97
+ msgstr "Όλα τα προγράμματα"
98
+
99
+ #: ../export-user-data.php:708
100
+ msgid "Registered"
101
+ msgstr "Εγγεγραμμένοι"
102
+
103
+ #: ../export-user-data.php:711
104
+ msgid "Start Date"
105
+ msgstr "Ημερομηνία Έναρξης"
106
+
107
+ #: ../export-user-data.php:715
108
+ msgid "End Date"
109
+ msgstr "Ημερομηνία Λήξης"
110
+
111
+ #: ../export-user-data.php:720
112
+ msgid "Pick a start and end user registration date to limit the results."
113
+ msgstr ""
114
+ "Επιλέξτε ημερομηνία έναρξης και λήξης για να περιορίσετε τα αποτελέσματα."
115
+
116
+ #: ../export-user-data.php:727
117
+ msgid "Limit Range"
118
+ msgstr "Εύρος"
119
+
120
+ #: ../export-user-data.php:729
121
+ msgid "Offset"
122
+ msgstr "Offset"
123
+
124
+ #: ../export-user-data.php:730
125
+ msgid "Total"
126
+ msgstr "Σύνολο"
127
+
128
+ #: ../export-user-data.php:733
129
+ #, php-format
130
+ msgid ""
131
+ "Enter an offset start number and a total number of users to export. <a href="
132
+ "\"%s\" target=\"_blank\">%s</a>"
133
+ msgstr ""
134
+ "Πληκτρολογήστε έναν offset αριθμό έναρξης και το συνολικό αριθμό των χρηστών "
135
+ "προς εξαγωγή. <a href=\"%s\" target=\"_blank\">%s</a>"
136
+
137
+ #: ../export-user-data.php:742
138
+ msgid "Format"
139
+ msgstr "Φορμάτ"
140
+
141
+ #: ../export-user-data.php:747
142
+ msgid "Excel"
143
+ msgstr "Excel"
144
+
145
+ #: ../export-user-data.php:748
146
+ msgid "CSV"
147
+ msgstr "CSV"
148
+
149
+ #: ../export-user-data.php:754
150
+ msgid "Select the format for the export file."
151
+ msgstr "Επιλέξτε το format για το αρχείο προς εξαγωγή."
152
+
153
+ #: ../export-user-data.php:762
154
+ msgid "Advanced Options"
155
+ msgstr "Σύνθετες επιλογές"
156
+
157
+ #: ../export-user-data.php:766 ../export-user-data.php:840
158
+ msgid "Show"
159
+ msgstr "Προβολή"
160
+
161
+ #: ../export-user-data.php:774
162
+ msgid "Export"
163
+ msgstr "Εξαγωγή"
164
+
165
+ #: ../export-user-data.php:838
166
+ msgid "Hide"
167
+ msgstr "Απόκρυψη"
readme.md CHANGED
@@ -2,8 +2,8 @@
2
  **Contributors:** qlstudio
3
  **Tags:** user, users, xprofile, usermeta csv, excel, batch, export, save, download
4
  **Requires at least:** 3.2
5
- **Tested up to:** 4.1.0
6
- **Stable tag:** 1.2.0
7
  **License:** GPLv2
8
 
9
  Export users data, metadata and buddypress xprofile data to a csv or Excel file
@@ -59,6 +59,13 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
59
 
60
  ## Changelog ##
61
 
 
 
 
 
 
 
 
62
  ### 1.2.0 ###
63
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
64
 
2
  **Contributors:** qlstudio
3
  **Tags:** user, users, xprofile, usermeta csv, excel, batch, export, save, download
4
  **Requires at least:** 3.2
5
+ **Tested up to:** 4.3.1
6
+ **Stable tag:** 1.2.1
7
  **License:** GPLv2
8
 
9
  Export users data, metadata and buddypress xprofile data to a csv or Excel file
59
 
60
  ## Changelog ##
61
 
62
+ ### 1.2.1 ###
63
+ * Checked on WP 4.3.1
64
+ * Moved text-domain to string in preperation for addition to translate.wordpress.org
65
+ * Added Log() method to allow for debugging to WP Error Log
66
+ * Added Greek translation - Thanks @Leonidas Mi
67
+ * Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
68
+
69
  ### 1.2.0 ###
70
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
71
 
readme.txt CHANGED
@@ -1,162 +1,174 @@
1
- === Export User Data ===
2
- Contributors: qlstudio
3
- Tags: user, users, xprofile, usermeta csv, excel, batch, export, save, download
4
- Requires at least: 3.2
5
- Tested up to: 4.1.0
6
- Stable tag: 1.2.0
7
- License: GPLv2
8
-
9
- Export users data, metadata and buddypress xprofile data to a csv or Excel file
10
-
11
- == Description ==
12
-
13
- A plugin that exports ALL user data, meta data and BuddyPress xProfile data.
14
-
15
- Includes an option to export the users by role, registration date range, usermeta option and two export formats.
16
-
17
- = Features =
18
-
19
- * Exports all users fields
20
- * Exports users meta
21
- * Exports users by role
22
- * Exports users by date range
23
- * Export user BuddyPress xProfile data
24
-
25
- For feature request and bug reports, [please use the WP Support Website](http://www.wp-support.co/view/categories/export-user-data).
26
-
27
- Please do not use the Wordpress.org forum to report bugs, as we no longer monitor or respond to questions there.
28
-
29
- == Installation ==
30
-
31
- For an automatic installation through WordPress:
32
-
33
- 1. Go to the 'Add New' plugins screen in your WordPress admin area
34
- 2. Search for 'Export User Data'
35
- 3. Click 'Install Now' and activate the plugin
36
- 4. Go the 'Export User Data' menu, under 'Users'
37
-
38
- For a manual installation via FTP:
39
-
40
- 1. Upload the `export-user-data` directory to the `/wp-content/plugins/` directory
41
- 2. Activate the plugin through the 'Plugins' screen in your WordPress admin area
42
- 3. Go the 'Export User Data' menu, under 'Users'
43
-
44
- To upload the plugin through WordPress, instead of FTP:
45
-
46
- 1. Upload the downloaded zip file on the 'Add New' plugins screen (see the 'Upload' tab) in your WordPress admin area and activate.
47
- 2. Go the 'Export User Data' menu, under 'Users'
48
-
49
- == Frequently Asked Questions ==
50
-
51
- = How to use? =
52
-
53
- Click on the 'Export User Data' link in the 'Users' menu, choose the role and the date range or don't select anything if you want to export all users, then click 'Export'. That's all!
54
-
55
- == Screenshots ==
56
-
57
- 1. User export screen
58
-
59
- == Changelog ==
60
-
61
- = 1.2.0 =
62
- * Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
63
-
64
- = 1.1.1 =
65
- * Removed accidently included .git files
66
-
67
- = 1.1.0 =
68
- * Version change to sync SVN on wordpress.org
69
-
70
- = 1.0.4 =
71
- * Added unserialize function with @ fallback
72
- * Removed anonymous function to allow support for PHP < 5.2
73
-
74
- = 1.0.3 =
75
- * Tested as working on WordPress 4.1.0.
76
-
77
- = 1.0.2 =
78
- * Removed get_user_meta method, as not effective.
79
- * Added registration date from and to pickers - to replace monthly <select> lists.
80
-
81
- = 1.0.1 =
82
- * Added recursive_implode() method to flatten data stored in arrays ( exported with keys and values divided by "|" )
83
-
84
- = 1.0.0 =
85
- * Reduced all get_user_meta queries to a single call to improve performance
86
- * Serialized data is now returned in it's pure stored format - not imploded or unserialized to avoid data structure loss
87
-
88
- = 0.9.9 =
89
- * get_uermeta renamed get_user_meta to be more consistent with WP
90
- * get_user_meta tidied up and tested on larger exports
91
- * added option to export user BP Groups
92
- * added option to export all user WP Roles
93
-
94
- = 0.9.8 =
95
- * added get_usermeta() to check if meta keys are unique and return an array if not
96
- * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
97
-
98
- = 0.9.7 =
99
- * Added known_arrays() filter to allow for array data to be returned correctly
100
-
101
- = 0.9.6 =
102
- * Save, load and delete stored export settings - thanks to @cwjordan
103
- * Overcome memory outages on large exports - thanks to @grexican
104
- * Tested on WP 4.0.0 & BP 2.1.0
105
-
106
- = 0.9.5 =
107
- * BP Serialized data fixes - thanks to @nicmare & @grexican
108
- * Tested on WP 3.9.2 & BP 2.0.2
109
-
110
- = 0.9.4 =
111
- * BP X Profile Export Fix ( > version 2.0 )
112
-
113
- = 0.9.3 =
114
- * fix for hidden admin bar
115
-
116
- = 0.9.2 =
117
- * removed $key assignment casting to integer
118
-
119
- = 0.9.1 =
120
- * Tested with WP 3.9
121
- * Fix for BuddyPress 2.0 bug
122
-
123
- = 0.9.0 =
124
- * Moved plugin class to singleton model
125
- * Improved language handling
126
- * French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
127
-
128
- = 0.8.3 =
129
- * clarified export limit options
130
-
131
- = 0.8.2 =
132
- * corrected buddypress export option - broken in 0.8.1
133
- * changed get_users arguments, in attempt to reduce memory usage
134
-
135
- = 0.8.1 =
136
- * Added experimental range limiter for exports
137
- * Extra input data sanitizing
138
-
139
- = 0.8 =
140
- * moved plugin instatiation to the WP hook: init
141
- * moved bp calls outside export loop
142
- * added extra isset calls on values in export loop to clean up error log not sets
143
-
144
- = 0.7.8 =
145
- * added xml template for Excel exports - thanks to phil@fixitlab.com :)
146
-
147
- = 0.7.2 =
148
- * fixes to allow exports without selecting extra user date from usermeta or x-profile
149
-
150
- = 0.6.3 =
151
- * added multiselect to pick usermeta and xprofile fields
152
-
153
- = 0.5 =
154
- * First public release.
155
-
156
- == Upgrade Notice ==
157
-
158
- = 0.6.3 =
159
- Latest.
160
-
161
- = 0.5 =
162
- First release.
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Export User Data ===
2
+ Contributors: qlstudio
3
+ Tags: user, users, xprofile, usermeta csv, excel, batch, export, save, download
4
+ Requires at least: 3.2
5
+ Tested up to: 4.3.1
6
+ Stable tag: 1.2.1
7
+ License: GPLv2
8
+
9
+ Export users data, metadata and buddypress xprofile data to a csv or Excel file
10
+
11
+ == Description ==
12
+
13
+ A plugin that exports ALL user data, meta data and BuddyPress xProfile data.
14
+
15
+ Includes an option to export the users by role, registration date range, usermeta option and two export formats.
16
+
17
+ = Features =
18
+
19
+ * Exports all users fields
20
+ * Exports users meta
21
+ * Exports users by role
22
+ * Exports users by date range
23
+ * Export user BuddyPress xProfile data
24
+
25
+ For feature request and bug reports, [please use the WP Support Website](http://www.wp-support.co/view/categories/export-user-data).
26
+
27
+ Please do not use the Wordpress.org forum to report bugs, as we no longer monitor or respond to questions there.
28
+
29
+ == Installation ==
30
+
31
+ For an automatic installation through WordPress:
32
+
33
+ 1. Go to the 'Add New' plugins screen in your WordPress admin area
34
+ 2. Search for 'Export User Data'
35
+ 3. Click 'Install Now' and activate the plugin
36
+ 4. Go the 'Export User Data' menu, under 'Users'
37
+
38
+ For a manual installation via FTP:
39
+
40
+ 1. Upload the `export-user-data` directory to the `/wp-content/plugins/` directory
41
+ 2. Activate the plugin through the 'Plugins' screen in your WordPress admin area
42
+ 3. Go the 'Export User Data' menu, under 'Users'
43
+
44
+ To upload the plugin through WordPress, instead of FTP:
45
+
46
+ 1. Upload the downloaded zip file on the 'Add New' plugins screen (see the 'Upload' tab) in your WordPress admin area and activate.
47
+ 2. Go the 'Export User Data' menu, under 'Users'
48
+
49
+ == Frequently Asked Questions ==
50
+
51
+ = How to use? =
52
+
53
+ Click on the 'Export User Data' link in the 'Users' menu, choose the role and the date range or don't select anything if you want to export all users, then click 'Export'. That's all!
54
+
55
+ == Screenshots ==
56
+
57
+ 1. User export screen
58
+
59
+ == Changelog ==
60
+
61
+ = 1.2.1 =
62
+ * Checked on WP 4.3.1
63
+ * Moved text-domain to string in preperation for addition to translate.wordpress.org
64
+ * Added Log() method to allow for debugging to WP Error Log
65
+ * Added Greek translation - Thanks @Leonidas Mi
66
+ * Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
67
+
68
+ = 1.2.0 =
69
+ * Data stored in recursive and serialized arrays is now exported in a flat string format with safer delimiters ( ||, ||| - etc. )
70
+ * Removed anonymous function calls giving errors on older versions of PHP
71
+
72
+ = 1.1.1 =
73
+ * Removed accidently included .git files
74
+
75
+ = 1.1.0 =
76
+ * Version change to sync SVN on wordpress.org
77
+
78
+ = 1.1.1 =
79
+ * Removed accidently included .git files
80
+
81
+ = 1.1.0 =
82
+ = 1.0.4 =
83
+ * Added unserialize function with @ fallback
84
+ * Removed anonymous function to allow support for PHP < 5.2
85
+
86
+ = 1.0.3 =
87
+ * Tested as working on WordPress 4.1.0.
88
+
89
+ = 1.0.2 =
90
+ * Removed get_user_meta method, as not effective.
91
+ * Added registration date from and to pickers - to replace monthly <select> lists.
92
+
93
+ = 1.0.1 =
94
+ * Added recursive_implode() method to flatten data stored in arrays ( exported with keys and values divided by "|" )
95
+
96
+ = 1.0.0 =
97
+ * Reduced all get_user_meta queries to a single call to improve performance
98
+ * Serialized data is now returned in it's pure stored format - not imploded or unserialized to avoid data structure loss
99
+
100
+ = 0.9.9 =
101
+ * get_uermeta renamed get_user_meta to be more consistent with WP
102
+ * get_user_meta tidied up and tested on larger exports
103
+ * added option to export user BP Groups
104
+ * added option to export all user WP Roles
105
+
106
+ = 0.9.8 =
107
+ * added get_usermeta() to check if meta keys are unique and return an array if not
108
+ * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
109
+
110
+ = 0.9.7 =
111
+ * Added known_arrays() filter to allow for array data to be returned correctly
112
+
113
+ = 0.9.6 =
114
+ * Save, load and delete stored export settings - thanks to @cwjordan
115
+ * Overcome memory outages on large exports - thanks to @grexican
116
+ * Tested on WP 4.0.0 & BP 2.1.0
117
+
118
+ = 0.9.5 =
119
+ * BP Serialized data fixes - thanks to @nicmare & @grexican
120
+ * Tested on WP 3.9.2 & BP 2.0.2
121
+
122
+ = 0.9.4 =
123
+ * BP X Profile Export Fix ( > version 2.0 )
124
+
125
+ = 0.9.3 =
126
+ * fix for hidden admin bar
127
+
128
+ = 0.9.2 =
129
+ * removed $key assignment casting to integer
130
+
131
+ = 0.9.1 =
132
+ * Tested with WP 3.9
133
+ * Fix for BuddyPress 2.0 bug
134
+
135
+ = 0.9.0 =
136
+ * Moved plugin class to singleton model
137
+ * Improved language handling
138
+ * French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
139
+
140
+ = 0.8.3 =
141
+ * clarified export limit options
142
+
143
+ = 0.8.2 =
144
+ * corrected buddypress export option - broken in 0.8.1
145
+ * changed get_users arguments, in attempt to reduce memory usage
146
+
147
+ = 0.8.1 =
148
+ * Added experimental range limiter for exports
149
+ * Extra input data sanitizing
150
+
151
+ = 0.8 =
152
+ * moved plugin instatiation to the WP hook: init
153
+ * moved bp calls outside export loop
154
+ * added extra isset calls on values in export loop to clean up error log not sets
155
+
156
+ = 0.7.8 =
157
+ * added xml template for Excel exports - thanks to phil@fixitlab.com :)
158
+
159
+ = 0.7.2 =
160
+ * fixes to allow exports without selecting extra user date from usermeta or x-profile
161
+
162
+ = 0.6.3 =
163
+ * added multiselect to pick usermeta and xprofile fields
164
+
165
+ = 0.5 =
166
+ * First public release.
167
+
168
+ == Upgrade Notice ==
169
+
170
+ = 0.6.3 =
171
+ Latest.
172
+
173
+ = 0.5 =
174
+ First release.