Export User Data - Version 1.3.0

Version Description

  • Added extra data sanitization before outputting to file - thanks to Hely Shah helyhshah@gmail.com for te heads-up
Download this release

Release Info

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

Code changes from version 1.2.7 to 1.3.0

Files changed (3) hide show
  1. export-user-data.php +798 -684
  2. readme.md +22 -11
  3. readme.txt +21 -10
export-user-data.php CHANGED
@@ -4,7 +4,7 @@
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.7
8
  Author: Q Studio
9
  Author URI: http://qstudio.us
10
  License: GPL2
@@ -14,143 +14,186 @@ Text Domain: export-user-data
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.7' ); // 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 = false;
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 = '0';
58
- private $user_fields = '1';
59
- private $groups = '0';
60
- private $start_date = '';
61
- private $end_date = '';
62
- private $limit_offset = '';
63
- private $limit_total = '';
64
- private $updated_since_date = '';
65
- private $field_updated_since = '';
66
- private $format = '';
67
-
68
-
69
- /**
70
- * Creates or returns an instance of this class.
71
- *
72
- * @return Foo A single instance of this class.
73
- */
74
- public static function get_instance() {
75
 
76
- if ( null == self::$instance ) {
77
- self::$instance = new self;
78
- }
79
 
80
- return self::$instance;
81
 
82
- }
83
-
84
-
85
  /**
86
  * Class contructor
87
  *
88
  * @since 0.1
89
  **/
90
- private function __construct()
91
  {
92
 
93
- if ( is_admin() ) {
94
-
95
- add_action( 'init', array( $this, 'load_plugin_textdomain' ), 100000001 );
96
- add_action( 'init', array( $this, 'load_user_options' ), 100000002 );
97
- add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
98
- add_action( 'init', array( $this, 'generate_data' ), 100000003 );
99
- add_filter( 'q_eud_exclude_data', array( $this, 'exclude_data' ) );
100
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 1 );
101
- add_action( 'admin_footer', array( $this, 'jquery' ), 100000 );
102
- add_action( 'admin_footer', array( $this, 'css' ), 100000 );
103
-
104
- }
105
 
106
  }
107
-
108
-
109
  /**
110
  * Load plugin text-domain
111
- *
112
  * @since 0.9.0
113
  * @return void
114
  **/
115
- public function load_plugin_textdomain()
116
  {
117
-
 
 
 
 
 
 
 
118
  load_plugin_textdomain( 'export-user-data', false, basename( dirname( __FILE__ ) ) . '/languages' );
119
-
120
  }
121
-
122
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  /**
124
- * Write to WP Error Log
125
- *
126
- * @since 1.2.1
127
- * @return void
128
- */
129
- public static function log( $log )
130
- {
131
-
132
- if ( true === WP_DEBUG ) {
133
-
134
- if ( is_array( $log ) || is_object( $log ) ) {
135
-
136
- error_log( print_r( $log, true ) );
137
-
138
- } else {
139
-
140
- error_log( $log );
141
-
142
- }
143
- }
144
-
145
- }
146
-
147
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  /**
149
  * Add administration menus
150
  *
151
  * @since 0.1
152
  **/
153
- public function add_admin_pages()
154
  {
155
 
156
  add_users_page( __( 'Export User Data', 'export-user-data' ), __( 'Export User Data', 'export-user-data' ), 'list_users', 'export-user-data', array( $this, 'users_page' ) );
@@ -159,56 +202,56 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
159
 
160
 
161
  /**
162
- * style and interaction
163
  */
164
- public function admin_enqueue_scripts( $hook )
165
  {
166
 
167
  // load the scripts on only the plugin admin page ##
168
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
169
 
170
- wp_register_style( 'q_export_user_data', plugins_url( 'css/export-user-data.css' ,__FILE__ ));
171
- wp_enqueue_style( 'q_export_user_data' );
172
  wp_enqueue_script( 'q_eud_multi_select_js', plugins_url( 'js/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
173
-
174
  // add script ##
175
  wp_enqueue_script('jquery-ui-datepicker');
176
 
177
  // add style ##
178
  wp_enqueue_style( 'jquery-ui-datepicker' );
179
  wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
180
-
181
- }
182
 
183
  }
184
-
185
-
186
  /**
187
  * Return Byte count of $val
188
- *
189
  * @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
190
  * @since 0.9.6
191
  */
192
- public function return_bytes( $val )
193
  {
194
-
195
  $val = trim( $val );
196
  $last = strtolower($val[strlen($val)-1]);
197
  switch( $last ) {
198
-
199
  // The 'G' modifier is available since PHP 5.1.0
200
  case 'g':
201
-
202
  $val *= 1024;
203
-
204
  case 'm':
205
-
206
  $val *= 1024;
207
-
208
  case 'k':
209
-
210
  $val *= 1024;
211
-
212
  }
213
 
214
  return $val;
@@ -216,96 +259,170 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
216
 
217
 
218
  /**
219
- * clean that stuff up
 
 
 
220
  */
221
- public static function sanitize( $value )
222
  {
223
 
 
224
  $value = str_replace("\r", '', $value);
225
  $value = str_replace("\n", '', $value);
226
  $value = str_replace("\t", '', $value);
 
 
 
 
 
 
 
 
227
  return $value;
228
 
229
  }
230
 
231
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  /**
233
  * Load up saved exports for this user
 
234
  *
235
  * @since 0.9.6
236
  * @return Array of saved exports
237
  */
238
  public function load_user_options()
239
  {
240
-
241
-
242
- $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() ;
 
 
 
243
  #var_dump( $this->q_eud_exports );
244
-
245
  }
246
-
247
-
248
  /**
249
  * Get list of saved exports for this user
250
  *
251
  * @since 0.9.4
252
  * @return Array of saved exports
253
  */
254
- public function get_user_options()
255
  {
256
-
257
  // get the stored options - filter empty array items ##
258
  $q_eud_exports = array_filter( $this->q_eud_exports );
259
-
260
  // quick check if the array is empty ##
261
- if ( empty ( $q_eud_exports ) ) {
262
-
263
- return false;
264
-
265
  }
266
-
267
  // test the array of saved exports ##
268
  #$this->pr( $q_eud_exports );
269
-
270
  // start with an empty array ##
271
  $exports = array();
272
-
273
  // loop over each saved export and grab each key ##
274
  foreach ( $q_eud_exports as $key => $value ) {
275
-
276
  $exports[] = $key;
277
-
278
  }
279
-
280
  // kick back array ##
281
  return( $exports );
282
-
283
  }
284
-
285
-
286
  /**
287
  * Check for and load stored user options
288
- *
289
  * @since 0.9.3
290
  * @return void
291
  */
292
- public function get_user_options_by_export( $export = null )
293
  {
294
-
295
  // sanity check ##
296
  if ( is_null ( $export ) ) { return false; }
297
-
298
  if ( isset( $this->q_eud_exports[$export] ) ) {
299
 
300
  $this->usermeta_saved_fields = $this->q_eud_exports[$export]['usermeta_saved_fields'];
301
  $this->bp_fields_saved_fields = $this->q_eud_exports[$export]['bp_fields_saved_fields'];
302
  $this->bp_fields_update_time_saved_fields = $this->q_eud_exports[$export]['bp_fields_update_time_saved_fields'];
303
- $this->updated_since_date = $this->q_eud_exports[$export]['updated_since_date'];
304
- $this->field_updated_since = $this->q_eud_exports[$export]['field_updated_since'];
305
  $this->role = $this->q_eud_exports[$export]['role'];
306
  $this->roles = $this->q_eud_exports[$export]['roles'];
307
  $this->groups = $this->q_eud_exports[$export]['groups'];
308
- $this->user_fields = $this->q_eud_exports[$export]['user_fields'];
309
  $this->start_date = $this->q_eud_exports[$export]['start_date'];
310
  $this->end_date = $this->q_eud_exports[$export]['end_date'];
311
  $this->limit_offset = $this->q_eud_exports[$export]['limit_offset'];
@@ -328,44 +445,44 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
328
  $this->limit_offset = '';
329
  $this->limit_total = '';
330
  $this->format = '';
331
-
332
  }
333
-
334
  }
335
-
336
 
337
  /**
338
- * method to store user options
339
  *
340
  * @param string $save_export Export Key name
341
  * @param array $save_options Array of export options to save
342
  * @since 0.9.3
343
  * @return void
344
  */
345
- public function set_user_options( $key = null, $options = null )
346
  {
347
-
348
  // sanity check ##
349
  if ( is_null ( $key ) || is_null ( $options ) ) {
350
-
351
  #$this->pr( 'missing save values' );
352
  return false;
353
-
354
  }
355
-
356
  #$this->pr( $key );
357
  #$this->pr( $options );
358
-
359
  // for now, I'm simply allowing keys to be resaved - but this is not so logical ##
360
- if ( array_key_exists( $key, $this->q_eud_exports ) ) {
361
-
362
  #$this->pr( 'key exists, skipping save' );
363
  #return false;
364
-
365
  }
366
-
367
  if ( isset( $options ) && is_array( $options ) ) {
368
-
369
  // update_option sanitizes the option name but not the option value ##
370
  foreach ( $options as $field_name => $field_value ) {
371
 
@@ -385,29 +502,29 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
385
  }
386
 
387
  }
388
-
389
  // assign the sanitized array of values to the class property $q_eud_exports as a new array with key $key ##
390
  $this->q_eud_exports[$key] = $options;
391
-
392
  // update stored user_meta values, if previous key found ##
393
  if ( get_user_meta( get_current_user_id(), 'q_eud_exports' ) !== false ) {
394
-
395
  #update_option( 'q_eud_exports', $this->q_eud_exports );
396
  update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
397
-
398
  // create new user meta key ##
399
  } else {
400
-
401
  #add_option( 'q_eud_exports', $this->q_eud_exports, $deprecated, $autoload );
402
  add_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
403
-
404
  }
405
-
406
  }
407
-
408
- }
409
-
410
-
411
  /**
412
  * method to delete user options
413
  *
@@ -415,69 +532,69 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
415
  * @since 0.9.3
416
  * @return void
417
  */
418
- public function delete_user_options( $key = null )
419
  {
420
-
421
  // sanity check ##
422
  if ( is_null ( $key ) || ! array_key_exists( $key, $this->q_eud_exports ) ) { return false; }
423
-
424
  // clean it up ##
425
  $key = sanitize_text_field( $key );
426
-
427
  // check it out ##
428
  #$this->pr( $key );
429
-
430
  // drop the array by it's key name from the class property ##
431
  unset( $this->q_eud_exports[$key] );
432
-
433
  // update the saved data ##
434
  update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
435
-
436
  }
437
-
438
-
439
  /**
440
  * Copy of BP_XProfile_ProfileData::get_all_for_user() from BP version 2.0?
441
  * Get all of the profile information for a specific user.
442
- *
443
  * @param $user_id Integer ID of specific user
444
  * @since 0.9.6
445
  * @return Array User profile fields
446
  * @deprecated since 1.2.1
447
  */
448
- private static function get_all_for_user( $user_id = null )
449
  {
450
-
451
  // sanity check ##
452
  if ( is_null( $user_id ) ) { return false; }
453
-
454
  global $wpdb, $bp;
455
-
456
  $bp = buddypress();
457
 
458
- $results = $wpdb->get_results(
459
- $wpdb->prepare(
460
  "
461
- 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
462
- FROM {$bp->profile->table_name_groups} g
463
- LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id
464
- 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
465
  WHERE d.user_id = %d AND d.value != ''
466
  "
467
- , $user_id
468
- )
469
  );
470
-
471
  $profile_data = array();
472
 
473
  if ( ! empty( $results ) ) {
474
-
475
  $profile_data['user_login'] = $results[0]->user_login;
476
  $profile_data['user_nicename'] = $results[0]->user_nicename;
477
  $profile_data['user_email'] = $results[0]->user_email;
478
 
479
  foreach( (array) $results as $field ) {
480
-
481
  $profile_data[$field->field_name] = array(
482
  'field_group_id' => $field->field_group_id,
483
  'field_group_name' => $field->field_group_name,
@@ -485,39 +602,44 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
485
  'field_type' => $field->field_type,
486
  'field_data' => $field->field_data
487
  );
488
-
489
  }
490
-
491
  }
492
 
493
  return $profile_data;
494
-
495
  }
496
-
497
-
498
  /**
499
- * Process content of CSV file
500
  *
501
  * @since 0.1
 
502
  **/
503
- public function generate_data()
504
  {
505
-
506
  // Check if the user clicked on the Save, Load, or Delete Settings buttons ##
507
- if (
508
  ! isset( $_POST['_wpnonce-q-eud-export-user-page_export'] )
509
  || isset( $_POST['load_export'] )
510
  || isset( $_POST['save_export'] )
511
- || isset( $_POST['delete_export'] ) )
512
  {
513
 
514
  return false;
515
 
516
  }
517
-
 
 
 
 
518
  // check admin referer ##
519
  check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' );
520
-
521
  // build argument array ##
522
  $args = array(
523
  'fields' => ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) ? 'all' : array( 'ID' ), // exclude standard wp_users fields from get_users query ##
@@ -535,31 +657,31 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
535
 
536
  // is there a range limit in place for the export ? ##
537
  if ( isset( $_POST['limit_total'] ) && $_POST['limit_total'] != '' ) {
538
-
539
  // let's just make sure they are integer values ##
540
  $limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
541
  $limit_total = (int)$_POST['limit_total'];
542
-
543
  if ( is_int( $limit_offset ) && is_int( $limit_total ) ) {
544
-
545
  $args['offset'] = $limit_offset;
546
- $args['number'] = $limit_total; // number - Limit the total number of users returned ##
547
-
548
  // test it ##
549
  #wp_die( $this->pr( $args ) );
550
-
551
  }
552
-
553
  }
554
-
555
  // pre_user query ##
556
  add_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
557
  $users = get_users( $args );
558
  remove_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
559
-
560
  // test args ##
561
  #wp_die( $this->pr ( $users ) );
562
-
563
  // no users found, so chuck an error into the args array and exit the export ##
564
  if ( ! $users ) {
565
 
@@ -567,7 +689,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
567
  exit;
568
 
569
  }
570
-
571
  // get sitename and clean it up ##
572
  $sitename = sanitize_key( get_bloginfo( 'name' ) );
573
  if ( ! empty( $sitename ) ) {
@@ -619,8 +741,8 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
619
  // to xls ##
620
  header( 'Content-Description: File Transfer' );
621
  header("Content-Type: application/vnd.ms-excel");
622
- header("Content-Disposition: attachment; filename=$filename.xls");
623
- header("Pragma: no-cache");
624
  header("Expires: 0");
625
 
626
  // set a csv check flag
@@ -653,13 +775,13 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
653
  $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
654
  #$this->pr( $usermeta );
655
  $usermeta_fields = array();
656
-
657
  if ( $usermeta && is_array( $usermeta ) ) {
658
  foreach( $usermeta as $field ) {
659
  $usermeta_fields[] = sanitize_text_field ( $field );
660
  }
661
  }
662
-
663
  #$this->pr( $usermeta_fields );
664
  #exit;
665
 
@@ -701,32 +823,36 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
701
  global $wpdb;
702
 
703
  // debug ##
704
- if ( self::debug ) self::log( 'generate_data(): merging array' );
705
-
706
  // compile final fields list ##
707
- $fields = array_merge(
708
- self::get_user_fields() // standard wp_user fields ##
709
- , self::get_special_fields() // 'special' fields - which are controlled via dedicated checks ##
710
  , $usermeta_fields // wp_user_meta fields ##
711
  , $bp_fields_passed // selected buddypress fields ##
712
  , $bp_fields_update_passed // update date for buddypress fields ##
713
  );
714
-
715
  // test field array ##
716
- #self::pr( $fields );
717
-
718
  // build the document headers ##
719
  $headers = array();
720
-
721
  foreach ( $fields as $key => $field ) {
722
 
 
 
723
  // rename programs field ##
724
  if ( $field == 'member_of_club' ){
725
  $field = 'Program';
726
  }
727
-
728
- // grab fields to exclude from exports ##
729
- if ( in_array( $field, $this->get_exclude_fields() ) ) {
 
 
730
 
731
  // ditch 'em ##
732
  unset( $fields[$key] );
@@ -747,29 +873,29 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
747
  }
748
 
749
  }
750
-
751
  // quick check ##
752
- #if ( self::debug ) self::log( 'All Fields: '. var_dump( $fields ) );
753
- #if ( self::debug ) self::log( '$bp_fields_passed: '. var_dump( $bp_fields_passed ) );
754
-
755
  // no more buffering while spitting back the export data ##
756
  ob_end_flush();
757
-
758
  // get the value in bytes allocated for Memory via php.ini ##
759
  // @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
760
  $memory_limit = $this->return_bytes( ini_get('memory_limit') ) * .75;
761
-
762
  // we need to disable caching while exporting because we export so much data that it could blow the memory cache
763
  // if we can't override the cache here, we'll have to clear it later...
764
  if ( function_exists( 'override_function' ) ) {
765
-
766
  override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
767
  override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
768
  override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
769
  override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
770
-
771
  } elseif ( function_exists( 'runkit_function_redefine' ) ) {
772
-
773
  runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
774
  runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
775
  runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
@@ -782,14 +908,14 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
782
 
783
  // echo headers ##
784
  echo $pre . implode( $seperator, $headers ) . $breaker;
785
-
786
- #wp_die( self::pr( $users ) );
787
-
788
  // build row values for each user ##
789
  foreach ( $users as $user ) {
790
-
791
- #wp_die( self::pr( $user ) );
792
-
793
  // check if we're hitting any Memory limits, if so flush them out ##
794
  // per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
795
  if ( memory_get_usage( true ) > $memory_limit ) {
@@ -798,62 +924,81 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
798
 
799
  // open up a new empty array ##
800
  $data = array();
801
-
802
- #wp_die( self::pr( $GLOBALS['bp'] ) );
803
-
804
  // BP loaded ? ##
805
- if ( function_exists ( 'bp_is_active' ) && bp_is_active( 'xprofile' ) ) {
806
-
807
- // grab all user data ##
808
- $bp_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID );
809
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
810
  }
811
-
812
  // single query method - get all user_meta data ##
813
  $get_user_meta = (array)get_user_meta( $user->ID );
814
- #wp_die( self::pr( $get_user_meta ) );
815
-
816
  // Filter out empty meta data ##
817
  #$get_user_meta = array_filter( array_map( function( $a ) {
818
  # return $a[0];
819
  #}, $get_user_meta ) );
820
-
821
  // loop over each field ##
822
  foreach ( $fields as $field ) {
823
-
824
  // check if this is a BP field ##
825
- if ( isset( $bp_data ) && isset( $bp_data[$field] ) && in_array( $field, $bp_fields_passed ) )
826
  {
827
-
828
  // old way from single BP query ##
829
  $value = $bp_data[$field];
830
-
831
  if ( is_array( $value ) ) {
832
-
833
  $value = maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
834
  #$value = $value['field_data'];
835
-
836
  /**
837
  * cwjordan
838
- * after unserializing it we then
839
- * need to implode it so
840
  * that we have something readable?
841
  * Going to use :: as a separator
842
  * because that's what Buddypress Members Import
843
- * expects, but we might want to make that
844
- * configurable.
845
  */
846
  if ( is_array( $value ) ) {
847
- $value = implode("::", $value );
848
  }
849
 
850
  }
851
-
852
- $value = self::sanitize($value);
 
853
 
854
  // check if this is a BP field we want the updated date for ##
855
- }
856
- elseif ( in_array( $field, $bp_fields_update_passed ) )
857
  {
858
 
859
  global $bp;
@@ -861,41 +1006,41 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
861
  $real_field = str_replace(" Update Date", "", $field);
862
  $field_id = xprofile_get_field_id_from_name( $real_field );
863
  $value = $wpdb->get_var (
864
- $wpdb->prepare(
865
  "
866
- SELECT last_updated
867
- FROM {$bp->profile->table_name_data}
868
  WHERE user_id = %d AND field_id = %d
869
  "
870
  , $user->ID
871
- , $field_id
872
- )
873
  );
874
 
875
  // include the user's role in the export ##
876
- }
877
  elseif ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] && $field == 'roles' )
878
  {
879
-
880
  // add "Role" as $value ##
881
  $value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
882
-
883
  // include the user's BP group in the export ##
884
- }
885
- elseif ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] && $field == 'groups' )
886
  {
887
-
888
  if ( function_exists( 'groups_get_user_groups' ) ) {
889
-
890
  // check if user is a member of any groups ##
891
  $group_ids = groups_get_user_groups( $user->ID );
892
-
893
- #self::pr( $group_ids );
894
  #wp_die( pr( 'loaded group data.' ));
895
-
896
- if ( ! $group_ids || $group_ids == '' ) {
897
 
898
- $value = '';
 
 
899
 
900
  } else {
901
 
@@ -903,9 +1048,9 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
903
  $groups = array();
904
 
905
  // loop over all groups ##
906
- foreach( $group_ids["groups"] as $group_id ) {
907
 
908
- $groups[] = groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
909
 
910
  }
911
 
@@ -915,68 +1060,74 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
915
  }
916
 
917
  } else {
918
-
919
  $value = '';
920
-
921
  }
922
-
923
- }
924
- elseif ( $field == 'bp_latest_update' )
925
  {
926
-
927
  // https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
928
  $value = bp_get_user_last_activity( $user->ID );
929
-
930
  // user or usermeta field ##
931
- }
932
- else
933
- {
934
-
935
  // the user_meta key isset ##
936
  if ( isset( $get_user_meta[$field] ) ) {
937
-
938
  // take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
939
  $value = $get_user_meta[$field][0];
940
-
941
  // standard WP_User value ##
942
  } else {
943
-
944
  // use the magically assigned value from WP_Users
945
- $value = $user->{$field};
946
-
947
  }
948
-
949
-
950
  // the $value might be serialized ##
951
- $value = self::unserialize( $value );
952
-
953
- // the value is an array ##
954
  if ( is_array ( $value ) ) {
955
 
956
  // recursive implode it ##
957
- $value = self::recursive_implode( $value );
958
 
959
  }
960
-
 
 
 
961
  }
962
-
963
-
964
  // correct program value to Program Name ##
965
  if ( $field == 'member_of_club' ) {
966
-
967
  $value = get_the_title($value);
968
-
969
  }
970
-
 
 
 
971
  // wrap values in quotes and add to array ##
972
  if ( $is_csv ) {
973
-
974
- $data[] = '"' . str_replace( '"', '""', self::special_characters( $value ) ) . '"';
975
-
976
  // just add to array ##
977
  } else {
978
-
979
- $data[] = self::special_characters( $value );
980
  }
981
 
982
  }
@@ -986,7 +1137,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
986
 
987
  }
988
 
989
- // close doc wrapper..
990
  echo $doc_end;
991
 
992
  // stop PHP, so file can export correctly ##
@@ -994,48 +1145,48 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
994
 
995
  }
996
 
997
-
998
  /**
999
  * Content of the settings page
1000
  *
1001
  * @since 0.1
1002
  **/
1003
- public function users_page()
1004
  {
1005
 
1006
  // quick security check ##
1007
  if ( ! current_user_can( 'list_users' ) ) {
1008
-
1009
  wp_die( __( 'You do not have sufficient permissions to access this page.', 'export-user-data' ) );
1010
-
1011
  }
1012
-
1013
  // Save settings button was pressed ##
1014
- if (
1015
- isset( $_POST['save_export'] )
1016
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1017
  ) {
1018
-
1019
  // start with an empty variable ##
1020
  $save_export = "";
1021
-
1022
  if ( ! empty( $_POST['save_new_export_name'] ) ) {
1023
-
1024
  // assign value ##
1025
  $save_export = $_POST['save_new_export_name'];
1026
-
1027
  } elseif ( ! empty( $_POST['export_name'] ) ) {
1028
-
1029
  $save_export = $_POST['export_name'];
1030
-
1031
  }
1032
 
1033
  // clean up $save_export ##
1034
  $save_export = sanitize_text_field( $save_export );
1035
-
1036
  // Build array of $options to save and save them ##
1037
  if ( isset( $save_export ) ) {
1038
-
1039
  // prepare all array values ##
1040
  $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
1041
  $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
@@ -1051,7 +1202,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1051
  $limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
1052
  $updated_since_date = isset ( $_POST['updated_since_date'] ) ? $_POST['updated_since_date'] : '' ;
1053
  $field_updated_since = isset ( $_POST['bp_field_updated_since'] ) ? $_POST['bp_field_updated_since'] : '';
1054
-
1055
  // assign all values to an array ##
1056
  $save_array = array (
1057
  'usermeta_saved_fields' => $usermeta,
@@ -1067,45 +1218,45 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1067
  'limit_total' => $limit_total,
1068
  'updated_since_date' => $updated_since_date,
1069
  'field_updated_since' => $field_updated_since,
1070
- 'format' => $format
1071
  );
1072
-
1073
  // store the options, for next load ##
1074
  $this->set_user_options( $save_export, $save_array );
1075
-
1076
  // Display the settings the user just saved instead of blanking the form ##
1077
  $_POST['load_export'] = 'Load Settings';
1078
  $_POST['export_name'] = $save_export;
1079
-
1080
  }
1081
-
1082
  }
1083
 
1084
  // Load settings button was pressed ( or option saved and $_POST variables hijacked )##
1085
- if (
1086
- isset( $_POST['load_export'] )
1087
- && isset( $_POST['export_name'] )
1088
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1089
  ) {
1090
-
1091
  $this->get_user_options_by_export( sanitize_text_field( $_POST['export_name'] ) );
1092
-
1093
  }
1094
-
1095
  // Delete settings button was pressed ##
1096
- if (
1097
- isset( $_POST['delete_export'] )
1098
- && isset( $_POST['export_name'] )
1099
- && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1100
  ) {
1101
-
1102
  $this->delete_user_options( sanitize_text_field( $_POST['export_name'] ) );
1103
-
1104
  }
1105
-
1106
  // what's in 'this' ? ##
1107
  #self:pr( $this );
1108
-
1109
  ?>
1110
  <div class="wrap">
1111
  <h2><?php _e( 'Export User Data', 'export-user-data' ); ?></h2>
@@ -1161,7 +1312,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1161
  $meta_keys_system = apply_filters( 'export_user_data_meta_keys_system', $meta_keys_system );
1162
 
1163
  // test array ##
1164
- #echo '<pre>'; var_dump($meta_keys); echo '</pre>';
1165
 
1166
  // check if we got anything ? ##
1167
  if ( $meta_keys ) {
@@ -1223,10 +1374,10 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1223
  }
1224
  ?>
1225
  </select>
1226
- <p class="description"><?php
1227
- printf(
1228
  __( 'Select the user meta keys to export, use the filters to simplify the list.', 'export-user-data' )
1229
- );
1230
  ?></p>
1231
  </td>
1232
  </tr>
@@ -1247,7 +1398,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1247
  $bp_fields = wp_list_pluck( $bp_fields, 'name' );
1248
 
1249
  // test array ##
1250
- #echo '<pre>'; var_dump($bp_fields); echo '</pre>';
1251
 
1252
  // allow array to be filtered ##
1253
  $bp_fields = apply_filters( 'export_user_data_bp_fields', $bp_fields );
@@ -1278,10 +1429,10 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1278
 
1279
  ?>
1280
  </select>
1281
- <p class="description"><?php
1282
- printf(
1283
  __( 'Select the BuddyPress XProfile keys to export', 'export-user-data' )
1284
- );
1285
  ?></p>
1286
  </td>
1287
  </tr>
@@ -1309,28 +1460,28 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1309
 
1310
  ?>
1311
  </select>
1312
- <p class="description"><?php
1313
- printf(
1314
  __( 'Select the BuddyPress XProfile keys updated dates to export', 'export-user-data' )
1315
- );
1316
  ?></p>
1317
  </td>
1318
  </tr>
1319
-
1320
  <tr valign="top" class="toggleable">
1321
  <th scope="row"><label for="groups"><?php _e( 'BP User Groups', 'export-user-data' ); ?></label></th>
1322
  <td>
1323
  <input id='groups' type='checkbox' name='groups' value='1' <?php checked( isset ( $this->groups ) ? intval ( $this->groups ) : '', 1 ); ?> />
1324
- <p class="description"><?php
1325
- printf(
1326
  __( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1327
  , esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
1328
  , 'Codex'
1329
- );
1330
  ?></p>
1331
  </td>
1332
  </tr>
1333
- <?php
1334
 
1335
  } // BP installed and active ##
1336
 
@@ -1339,25 +1490,21 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1339
  <th scope="row"><label for="user_fields"><?php _e( 'Standard User Fields', 'export-user-data' ); ?></label></th>
1340
  <td>
1341
  <input id='user_fields' type='checkbox' name='user_fields' value='1' <?php checked( isset ( $this->user_fields ) ? intval ( $this->user_fields ) : '', 1 ); ?> />
1342
- <p class="description"><?php
1343
-
1344
- if ( self::debug ) {
1345
-
1346
- self::log( 'user_fields: '.$this->user_fields );
1347
- #echo 'user_fields: '. $this->user_fields;
1348
-
1349
- }
1350
-
1351
- printf(
1352
  __( 'Include Standard user profile fields, such as user_login. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1353
  , esc_html('https://codex.wordpress.org/Database_Description#Table:_wp_users')
1354
  , 'Codex'
1355
- );
1356
-
1357
  ?></p>
1358
  </td>
1359
  </tr>
1360
-
1361
  <tr valign="top" class="toggleable">
1362
  <th scope="row"><label for="q_eud_users_role"><?php _e( 'Role', 'export-user-data' ); ?></label></th>
1363
  <td>
@@ -1366,43 +1513,43 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1366
 
1367
  echo '<option value="">' . __( 'All Roles', 'export-user-data' ) . '</option>';
1368
  global $wp_roles;
1369
-
1370
  foreach ( $wp_roles->role_names as $role => $name ) {
1371
-
1372
  if ( isset ( $this->role ) && ( $this->role == $role ) ) {
1373
-
1374
  echo "\n\t<option selected value='" . esc_attr( $role ) . "'>$name</option>";
1375
-
1376
  } else {
1377
-
1378
  echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1379
-
1380
  }
1381
  }
1382
 
1383
 
1384
  ?>
1385
  </select>
1386
- <p class="description"><?php
1387
- printf(
1388
  __( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1389
  , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1390
  , 'Codex'
1391
- );
1392
  ?></p>
1393
  </td>
1394
  </tr>
1395
-
1396
  <tr valign="top" class="toggleable">
1397
  <th scope="row"><label for="roles"><?php _e( 'User Roles', 'export-user-data' ); ?></label></th>
1398
  <td>
1399
  <input id='roles' type='checkbox' name='roles' value='1' <?php checked( isset ( $this->roles ) ? intval ( $this->roles ) : '', 1 ); ?> />
1400
- <p class="description"><?php
1401
- printf(
1402
  __( 'Include all of the users <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1403
  , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1404
  , 'Roles'
1405
- );
1406
  ?></p>
1407
  </td>
1408
  </tr>
@@ -1422,7 +1569,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1422
 
1423
  $clubs_array = get_posts(array( 'post_type'=> 'club', 'posts_per_page' => -1 )); // grab all posts of type "club" ##
1424
 
1425
- foreach ( $clubs_array as $c ) { // loop over all clubs ##
1426
 
1427
  #$clubs[$c->ID] = $c; // grab club ID ##
1428
  echo "\n\t<option value='" . esc_attr( $c->ID ) . "'>$c->post_title</option>";
@@ -1443,25 +1590,25 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1443
  <td>
1444
  <input type="text" id="q_eud_users_start_date" name="start_date" value="<?php echo $this->start_date; ?>" class="start-datepicker" />
1445
  <input type="text" id="q_eud_users_end_date" name="end_date" value="<?php echo $this->end_date; ?>" class="end-datepicker" />
1446
- <p class="description"><?php
1447
- printf(
1448
  __( 'Pick a start and end user registration date to limit the results.', 'export-user-data' )
1449
- );
1450
  ?></p>
1451
  </td>
1452
  </tr>
1453
-
1454
  <tr valign="top" class="toggleable">
1455
  <th scope="row"><label><?php _e( 'Limit Range', 'export-user-data' ); ?></label></th>
1456
  <td>
1457
  <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' ); ?>">
1458
  <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' ); ?>">
1459
- <p class="description"><?php
1460
- printf(
1461
  __( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1462
  , esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
1463
  , 'Codex'
1464
- );
1465
  ?></p>
1466
  </td>
1467
  </tr>
@@ -1484,10 +1631,10 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1484
  ?>
1485
  </select>
1486
 
1487
- <p class="description"><?php
1488
- printf(
1489
  __( 'Limit the results to users who have updated this extended profile field after this date.', 'export-user-data' )
1490
- );
1491
  ?></p>
1492
  </td>
1493
  </tr>
@@ -1509,14 +1656,14 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1509
  }
1510
  ?>
1511
  </select>
1512
- <p class="description"><?php
1513
- printf(
1514
  __( 'Select the format for the export file.', 'export-user-data' )
1515
- );
1516
  ?></p>
1517
  </td>
1518
  </tr>
1519
-
1520
  <tr valign="top" class="remember">
1521
  <th scope="row"><label for="q_eud_save_options"><?php _e( 'Stored Options', 'export-user-data' ); ?></label></th>
1522
  <td>
@@ -1533,16 +1680,16 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1533
  ?>
1534
  <div class="row">
1535
  <select name="export_name" id="q_eud_save_options" class="regular-text">
1536
- <?php
1537
 
1538
  // loop over each saved export ##
1539
  foreach( $this->get_user_options() as $export ) {
1540
 
1541
  // select Loaded export name, if selected ##
1542
- if (
1543
- isset( $_POST['load_export'] )
1544
- && isset( $_POST['export_name'] )
1545
- && ( $_POST['export_name'] == $export )
1546
  ) {
1547
 
1548
  echo "<option selected value='$export'>$export</option>";
@@ -1555,7 +1702,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1555
  }
1556
 
1557
  }
1558
-
1559
  ?>
1560
  </select>
1561
 
@@ -1565,13 +1712,13 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1565
 
1566
  }
1567
 
1568
- ?>
1569
  </div>
1570
  <p class="description"><?php _e( 'Save, load or delete your stored export options.', 'export-user-data' ); ?></p>
1571
-
1572
  </td>
1573
  </tr>
1574
-
1575
  <tr valign="top">
1576
  <th scope="row">
1577
  <label for="q_eud_xprofile"><?php _e( 'Advanced Options', 'export-user-data' ); ?></label>
@@ -1582,7 +1729,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1582
  </div>
1583
  </td>
1584
  </tr>
1585
-
1586
  </table>
1587
  <p class="submit">
1588
  <input type="hidden" name="_wp_http_referer" value="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" />
@@ -1590,33 +1737,34 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1590
  </p>
1591
  </form>
1592
  </div>
1593
-
1594
  <?php
1595
  }
1596
 
1597
-
1598
  /**
1599
  * Inline jQuery
1600
  * @since 0.8.2
1601
  */
1602
- public function jquery()
1603
  {
1604
 
1605
- // load the scripts on only the plugin admin page
1606
  if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
 
1607
  ?>
1608
  <script>
1609
-
1610
  // lazy load in some jQuery validation ##
1611
  jQuery(document).ready(function($) {
1612
 
1613
  // build super multiselect ##
1614
  jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
1615
-
1616
  //Select any fields from saved settings ##
1617
- jQuery('#usermeta').multiSelect('select',([<?php echo( self::quote_array( $this->usermeta_saved_fields ) ); ?>]));
1618
- jQuery('#bp_fields').multiSelect('select',([<?php echo( self::quote_array($this->bp_fields_saved_fields ) ); ?>]));
1619
- jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( self::quote_array( $this->bp_fields_update_time_saved_fields ) ); ?>]));
1620
 
1621
  // show only common ##
1622
  jQuery('.usermeta-common').click(function(e){
@@ -1635,7 +1783,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1635
  e.preventDefault();
1636
  jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
1637
  });
1638
-
1639
  // select none ##
1640
  jQuery('.select-none').click(function(e){
1641
  e.preventDefault();
@@ -1662,7 +1810,7 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1662
  }
1663
 
1664
  });
1665
-
1666
  // toggle advanced options ##
1667
  jQuery(".toggle a").click( function(e) {
1668
  e.preventDefault();
@@ -1674,59 +1822,67 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1674
  jQuery(this).text("<?php _e( 'Show', 'export-user-data' ); ?>");
1675
  }
1676
  });
1677
-
1678
  // validate save button ##
1679
  jQuery("#save_export").click( function(e) {
1680
-
1681
  // grab the value of the input ##
1682
  var q_eud_save_options_new_export = jQuery('#q_eud_save_options_new_export').val();
1683
-
1684
  if ( ! q_eud_save_options_new_export || q_eud_save_options_new_export == '' ) {
1685
-
1686
  e.preventDefault(); // stop things here ##
1687
  jQuery('#q_eud_save_options_new_export').addClass("error");
1688
-
1689
  }
1690
-
1691
  });
1692
-
1693
  // remove validation on focus ##
1694
  jQuery("body").on( 'focus', '#q_eud_save_options_new_export', function(e) {
1695
-
1696
  jQuery(this).removeClass("error");
1697
-
1698
  });
1699
-
1700
- <?php
1701
-
1702
  // method returns an object with "first" & "last" keys ##
1703
- $dates = self::get_user_registered_dates();
1704
-
 
 
 
 
 
1705
  ?>
1706
-
1707
  // start date picker ##
1708
  jQuery('.start-datepicker').datepicker( {
1709
- dateFormat : 'yy-mm-dd',
1710
  minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1711
- maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
 
1712
  } );
1713
-
1714
  // end date picker ##
1715
  jQuery('.end-datepicker').datepicker( {
1716
- dateFormat : 'yy-mm-dd',
1717
  minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1718
- maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>'
 
1719
  } );
1720
-
1721
  // end date picker ##
1722
  // might want to set minDate to something else, but not sure
1723
  // what would be best for everyone
1724
- jQuery('.updated-datepicker').datepicker( {
1725
- dateFormat : 'yy-mm-dd',
1726
- minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1727
- maxDate : '0'
1728
- } );
1729
-
 
1730
  });
1731
 
1732
  </script>
@@ -1734,16 +1890,16 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1734
  }
1735
 
1736
  }
1737
-
1738
-
1739
- /**
1740
  * Inline CSS
1741
  * @since 0.8.2
1742
  */
1743
- public function css()
1744
  {
1745
 
1746
- // load the scripts on only the plugin admin page
1747
  if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
1748
  ?>
1749
  <style>
@@ -1754,36 +1910,37 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1754
  }
1755
 
1756
  }
1757
-
1758
-
1759
  /**
1760
  * Data to exclude from export
1761
  */
1762
- public function get_exclude_fields()
1763
  {
1764
-
1765
  $exclude_fields = array (
1766
  'user_pass'
 
1767
  #, 'user_activation_key'
1768
  );
1769
-
1770
  return apply_filters( 'export_user_data_exclude_fields', $exclude_fields );
1771
 
1772
  }
1773
-
1774
-
1775
  /**
1776
  * Get the array of standard WP_User fields to return
1777
  */
1778
- public static function get_user_fields()
1779
  {
1780
-
1781
  // standard wp_users fields ##
1782
  if ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) {
1783
-
1784
  // debug ##
1785
- if ( self::debug ) self::log( 'get_user_fields(): full' );
1786
-
1787
  // exportable user data ##
1788
  $user_fields = array(
1789
  'ID'
@@ -1797,61 +1954,61 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1797
  , 'user_status'
1798
  , 'display_name'
1799
  );
1800
-
1801
  } else {
1802
-
1803
  // debug ##
1804
- if ( self::debug ) self::log( 'get_user_fields(): reduced' );
1805
-
1806
- // just return the user ID
1807
  $user_fields = array(
1808
  'ID'
1809
  );
1810
-
1811
  }
1812
-
1813
  // kick back values ##
1814
  return apply_filters( 'export_user_data_user_fields', $user_fields );
1815
 
1816
  }
1817
-
1818
-
1819
  /**
1820
  * Get the array of special user fields to return
1821
  */
1822
- public static function get_special_fields()
1823
  {
1824
-
1825
  // exportable user data ##
1826
  $special_fields = array(
1827
  # 'roles' // list of WP Roles
1828
  #, 'groups' // BP Groups
1829
  );
1830
-
1831
  // should we allow groups ##
1832
  if ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] ) {
1833
-
1834
  $special_fields[] = 'groups'; // add groups ##
1835
-
1836
  }
1837
-
1838
  // should we allow groups ##
1839
  if ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] ) {
1840
-
1841
  $special_fields[] = 'roles'; // add groups ##
1842
-
1843
  }
1844
-
1845
  // kick back the array ##
1846
  return apply_filters( 'export_user_data_special_fields', $special_fields );
1847
 
1848
  }
1849
-
1850
-
1851
  /*
1852
  * Pre User Query
1853
  */
1854
- public function pre_user_query( $user_search )
1855
  {
1856
 
1857
  global $wpdb;
@@ -1859,40 +2016,44 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1859
  $where = '';
1860
 
1861
  if ( ! empty( $_POST['start_date'] ) ) {
1862
-
1863
  $date = new DateTime( sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
1864
  $date_formatted = $date->format( 'Y-m-d H:i:s' );
1865
-
1866
  $where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
1867
-
1868
  }
1869
  if ( ! empty( $_POST['end_date'] ) ) {
1870
-
1871
  $date = new DateTime( sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
1872
  $date_formatted = $date->format( 'Y-m-d H:i:s' );
1873
-
1874
  $where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
1875
-
1876
  }
1877
-
1878
- //search by last update time of BP extended fields
1879
- if ( ( isset ($_POST['updated_since_date'] ) && $_POST['updated_since_date'] != '' ) &&
1880
- (isset ($_POST['bp_field_updated_since'] ) && $_POST['bp_field_updated_since'] != '' ) ) {
1881
- $last_updated_date = new DateTime( sanitize_text_field ( $_POST['updated_since_date'] ) . ' 00:00:00' );
1882
- $this->updated_since_date = $last_updated_date->format( 'Y-m-d H:i:s' );
1883
- $this->field_updated_since = sanitize_text_field ( $_POST['bp_field_updated_since'] );
1884
- $field_updated_since_id = BP_Xprofile_Field::get_id_from_name( $this->field_updated_since );
1885
- $user_search->query_from .= " JOIN `wp_bp_xprofile_data` XP ON XP.user_id = wp_users.ID ";
1886
- $where .= $wpdb->prepare( " AND XP.field_id = %s AND XP.last_updated >= %s", $field_updated_since_id, $this->updated_since_date );
 
 
 
 
1887
  }
1888
-
1889
  if ( ! empty( $where ) ) {
1890
-
1891
  $user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
1892
-
1893
  }
1894
 
1895
- #wp_die( self::pr( $user_search ) );
1896
  return $user_search;
1897
 
1898
  }
@@ -1900,21 +2061,21 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1900
 
1901
  /**
1902
  * Export Date Options
1903
- *
1904
  * @since 0.9.6
1905
  * @global type $wpdb
1906
  * @return Array of objects
1907
  */
1908
- private static function get_user_registered_dates()
1909
  {
1910
-
1911
  // invite in global objects ##
1912
  global $wpdb;
1913
-
1914
  // query user table for oldest and newest registration ##
1915
- $range =
1916
- $wpdb->get_results (
1917
- #$wpdb->prepare (
1918
  "
1919
  SELECT
1920
  MIN( user_registered ) AS first,
@@ -1924,76 +2085,21 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
1924
  "
1925
  #)
1926
  );
1927
-
1928
- return $range;
1929
-
1930
- /*
1931
- // invite in global objects ##
1932
- global $wpdb, $wp_locale;
1933
-
1934
- // grab list of years and months available
1935
- $months = $wpdb->get_results( "
1936
- SELECT DISTINCT YEAR( user_registered ) AS year, MONTH( user_registered ) AS month, DAY( user_registered ) AS day
1937
- FROM $wpdb->users
1938
- ORDER BY user_registered DESC
1939
- " );
1940
-
1941
- // check if we got a result ##
1942
- $month_count = count( $months );
1943
-
1944
- // nothing cokking ##
1945
- if ( ! $month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) {
1946
-
1947
- return;
1948
-
1949
- }
1950
-
1951
- #wp_die( self::pr( $months ) );
1952
-
1953
- // loop over each month ##
1954
- foreach ( $months as $date ) {
1955
-
1956
- // skip if year == '0' ##
1957
- if ( 0 == $date->year ) {
1958
- continue;
1959
- }
1960
-
1961
- // make sure the month is in a MM two digit format ##
1962
- $month = zeroise( $date->month, 2 );
1963
-
1964
- // build up a tae string - YYYY-MM ##
1965
- $date_string = $date->year . '-' . $month;
1966
-
1967
- // check if passed date matches this string ##
1968
- if ( $selected_date == $date_string ) {
1969
-
1970
- ?>
1971
- <option selected value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1972
- <?php
1973
-
1974
- } else {
1975
-
1976
- ?>
1977
- <option value="<?php echo $date_string; ?>"><?php echo $wp_locale->get_month( $month ); ?> <?php echo $date->year; ?></option>
1978
- <?php
1979
-
1980
- }
1981
 
1982
- }
1983
- */
1984
 
1985
  }
1986
 
1987
-
1988
  /**
1989
  * Quote array elements and separate with commas
1990
  *
1991
  * @since 0.9.6
1992
  * @return String
1993
  */
1994
- private static function quote_array( $array )
1995
  {
1996
-
1997
  $prefix = ''; // starts empty ##
1998
  $elementlist = '';
1999
  if ( is_array( $array ) ) {
@@ -2002,102 +2108,102 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
2002
  $prefix = ','; // prefix all remaining items with a comma ##
2003
  }
2004
  }
2005
-
2006
  // kick back string to function caller ##
2007
  return( $elementlist );
2008
-
2009
  }
2010
-
2011
-
2012
  /**
2013
- * Recursively implodes an array
2014
- *
2015
- * @since 1.0.1
2016
- * @access public
2017
- * @param array $array multi-dimensional array to recursively implode
2018
- * @param string $glue value that glues elements together
2019
- * @param bool $include_keys include keys before their values
2020
- * @param bool $trim_all trim ALL whitespace from string
2021
- * @return string imploded array
2022
- */
2023
- public static function recursive_implode( $array, $return = null, $glue = '|' )
2024
  {
2025
-
2026
  // unserialize ##
2027
- $array = self::unserialize( $array );
2028
-
2029
  // kick it back ##
2030
- if ( is_null ( $return ) && ! is_array( $array ) ) {
2031
-
2032
  return $array;
2033
-
2034
  }
2035
-
2036
  // empty return ##
2037
- if ( is_null ( $return ) ) {
2038
-
2039
- $return = '';
2040
-
2041
  } else {
2042
-
2043
  if ( "||" == $glue ) {
2044
-
2045
  $glue = '|||';
2046
-
2047
  } else if ( "|" == $glue ) {
2048
-
2049
  $glue = '||';
2050
-
2051
  }
2052
-
2053
  }
2054
-
2055
  // loop ##
2056
  foreach( $array as $key => $value ) {
2057
-
2058
  // unserialize ##
2059
- $value = self::unserialize( $value );
2060
-
2061
  if( is_array( $value ) ) {
2062
-
2063
- $return .= $glue . $key . $glue . self::recursive_implode( $value, $return, $glue );
2064
-
2065
  } else {
2066
-
2067
  $return .= $glue . $key . $glue . $value;
2068
-
2069
  }
2070
-
2071
  }
2072
 
2073
  // Removes first $glue from string ##
2074
- if ( $glue && $return && $return[0] == '|' ) {
2075
 
2076
  $return = ltrim ( $return, '|' );
2077
-
2078
  }
2079
-
2080
  // Trim ALL whitespace ##
2081
  if ( $return ) {
2082
-
2083
  $return = preg_replace( "/(\s)/ixsm", '', $return );
2084
-
2085
  }
2086
-
2087
  // kick it back ##
2088
  return $return;
2089
-
2090
- }
2091
-
2092
-
2093
  /**
2094
  * Save Unserializer
2095
- *
2096
  * @since 1.1.4
2097
  */
2098
- public static function unserialize( $value )
2099
  {
2100
-
2101
  // the $value is serialized ##
2102
  if ( is_serialized( $value ) ) {
2103
 
@@ -2119,51 +2225,59 @@ if ( ! class_exists( 'Q_Export_User_Data' ) )
2119
  }
2120
 
2121
  }
2122
-
2123
  // kick it back ##
2124
  return $value;
2125
-
2126
  }
2127
-
2128
-
2129
  /**
2130
  * Encode special characters
2131
- *
2132
  * @param type $string
2133
  * @return string Encoding string
2134
  * @since 1.2.3
2135
  */
2136
- public static function special_characters( $string = null )
2137
  {
2138
-
2139
  // sanity check ##
2140
  if ( is_null( $string ) ) {
2141
-
2142
  return false;
2143
-
2144
  }
2145
-
2146
  // kick it back in a nicer format ##
2147
  return htmlentities( $string, ENT_COMPAT, 'UTF-8' );
2148
-
2149
  }
2150
-
2151
-
2152
- /**
2153
- * Nicer var_dump
2154
- *
2155
- * @since 0.9.6
2156
- */
2157
- public static function pr ( $variable )
2158
- {
2159
-
2160
- echo '<pre>';
2161
- print_r ( $variable );
2162
- echo '</pre>';
2163
-
2164
- }
2165
 
2166
 
2167
  }
2168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2169
  }
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.3.0
8
  Author: Q Studio
9
  Author URI: http://qstudio.us
10
  License: GPL2
14
  // quick check :) ##
15
  defined( 'ABSPATH' ) OR exit;
16
 
 
 
 
 
17
  /* Check for Class */
18
+ if ( ! class_exists( 'Q_Export_User_Data' ) )
19
  {
20
+
21
  // plugin version
22
+ define( 'Q_EUD_HOOK', 'init' ); // wp action to hook to ##
23
+ define( 'Q_EUD_PRIORITY', '1000000' ); // priority ##
24
+ define( 'Q_LOG_PREFIX', 'EUD' ); // wp action to hook to ##
25
+
26
+ // plugin version
27
+ define( 'Q_EUD', '1.3.0' ); // version ##
28
+
29
+ // on activate ##
30
+ #register_activation_hook( __FILE__, 'function' );
31
+
32
+ // on deactivate ##
33
+ #register_deactivation_hook( __FILE__, 'function' );
34
 
 
 
 
35
  /**
36
  * Main plugin class
37
  *
38
  * @since 0.1
39
  **/
40
  class Q_Export_User_Data {
41
+
42
+
43
+ #private static $instance = null;
44
+
 
 
 
45
  /* properties */
46
+ #protected $text_domain = 'export-user-data'; // for translation ##
47
+ protected $debug = true; // debug ##
48
+ protected $q_eud_exports = ''; // export settings ##
49
+ protected $usermeta_saved_fields = array();
50
+ protected $bp_fields_saved_fields = array();
51
+ protected $bp_fields_update_time_saved_fields = array();
52
+ protected $role = '';
53
+ protected $roles = '0';
54
+ protected $user_fields = '1';
55
+ protected $groups = '0';
56
+ protected $start_date = '';
57
+ protected $end_date = '';
58
+ protected $limit_offset = '';
59
+ protected $limit_total = '';
60
+ protected $updated_since_date = '';
61
+ protected $field_updated_since = '';
62
+ protected $format = '';
63
+ protected $bp_data_available = false;
64
+ protected $allowed_tags = '';
 
 
 
 
 
65
 
 
 
 
66
 
 
67
 
 
 
 
68
  /**
69
  * Class contructor
70
  *
71
  * @since 0.1
72
  **/
73
+ public function __construct()
74
  {
75
 
76
+ // silence is golden ##
 
 
 
 
 
 
 
 
 
 
 
77
 
78
  }
79
+
80
+
81
  /**
82
  * Load plugin text-domain
83
+ *
84
  * @since 0.9.0
85
  * @return void
86
  **/
87
+ public function load_plugin_textdomain()
88
  {
89
+
90
+ // The "plugin_locale" filter is also used in load_plugin_textdomain()
91
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'export-user-data' );
92
+
93
+ // try from global WP location first ##
94
+ load_textdomain( 'export-user-data', WP_LANG_DIR.'/plugins/export-user-data-'.$locale.'.mo' );
95
+
96
+ // try from plugin last ##
97
  load_plugin_textdomain( 'export-user-data', false, basename( dirname( __FILE__ ) ) . '/languages' );
98
+
99
  }
100
+
101
+
102
+ /**
103
+ * Hook intro WP filters and actions
104
+ *
105
+ * @since 1.2.8
106
+ * @return void
107
+ */
108
+ public function run_hooks()
109
+ {
110
+
111
+ // set text domain ##
112
+ add_action( 'init', array( $this, 'load_plugin_textdomain' ), 1 );
113
+
114
+ if ( is_admin() ) {
115
+
116
+ // load BP ##
117
+ add_action( Q_EUD_HOOK, array( $this, 'load_buddypress' ), Q_EUD_PRIORITY+1 );
118
+
119
+ // load user options ##
120
+ add_action( Q_EUD_HOOK, array( $this, 'load_user_options' ), Q_EUD_PRIORITY+2 );
121
+
122
+ // run export ##
123
+ add_action( Q_EUD_HOOK, array( $this, 'generate_data' ), Q_EUD_PRIORITY+3 );
124
+
125
+ // filter exported data - perhaps unused ##
126
+ #add_filter( 'q_eud_exclude_data', array( $this, 'exclude_data' ) );
127
+
128
+ // add export page inside admin ##
129
+ add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
130
+
131
+ // UI style and functionality ##
132
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 1 );
133
+ add_action( 'admin_footer', array( $this, 'jquery' ), 100000 );
134
+ add_action( 'admin_footer', array( $this, 'css' ), 100000 );
135
+
136
+ }
137
+
138
+ }
139
+
140
+
141
  /**
142
+ * Write to WP Error Log
143
+ *
144
+ * @since 1.5.0
145
+ * @return void
146
+ */
147
+ protected function log( $log )
148
+ {
149
+
150
+ if ( $this->debug && true === WP_DEBUG ) {
151
+
152
+ $trace = debug_backtrace();
153
+ $caller = $trace[1];
154
+
155
+ $suffix = sprintf(
156
+ __( ' - %s%s() %s:%d', 'Q_Scrape_Wordpress' )
157
+ , isset($caller['class']) ? $caller['class'].'::' : ''
158
+ , $caller['function']
159
+ , isset( $caller['file'] ) ? $caller['file'] : 'n'
160
+ , isset( $caller['line'] ) ? $caller['line'] : 'x'
161
+ );
162
+
163
+ $prefix = Q_LOG_PREFIX.' ';
164
+
165
+ if ( is_array( $log ) || is_object( $log ) ) {
166
+ error_log( $prefix.print_r( $log, true ).$suffix );
167
+ } else {
168
+ error_log( $prefix.$log.$suffix );
169
+ }
170
+
171
+ }
172
+
173
+ }
174
+
175
+
176
+ /**
177
+ * Nicer var_dump
178
+ *
179
+ * @since 0.9.6
180
+ */
181
+ protected function pr ( $variable )
182
+ {
183
+
184
+ echo '<pre>';
185
+ print_r ( $variable );
186
+ echo '</pre>';
187
+
188
+ }
189
+
190
+
191
  /**
192
  * Add administration menus
193
  *
194
  * @since 0.1
195
  **/
196
+ public function add_admin_pages()
197
  {
198
 
199
  add_users_page( __( 'Export User Data', 'export-user-data' ), __( 'Export User Data', 'export-user-data' ), 'list_users', 'export-user-data', array( $this, 'users_page' ) );
202
 
203
 
204
  /**
205
+ * style and interaction
206
  */
207
+ public function admin_enqueue_scripts( $hook )
208
  {
209
 
210
  // load the scripts on only the plugin admin page ##
211
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
212
 
213
+ wp_register_style( 'css-q_export_user_data', plugins_url( 'css/export-user-data.css' ,__FILE__ ), '', Q_EUD );
214
+ wp_enqueue_style( 'css-q_export_user_data' );
215
  wp_enqueue_script( 'q_eud_multi_select_js', plugins_url( 'js/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
216
+
217
  // add script ##
218
  wp_enqueue_script('jquery-ui-datepicker');
219
 
220
  // add style ##
221
  wp_enqueue_style( 'jquery-ui-datepicker' );
222
  wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
223
+
224
+ }
225
 
226
  }
227
+
228
+
229
  /**
230
  * Return Byte count of $val
231
+ *
232
  * @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
233
  * @since 0.9.6
234
  */
235
+ protected function return_bytes( $val )
236
  {
237
+
238
  $val = trim( $val );
239
  $last = strtolower($val[strlen($val)-1]);
240
  switch( $last ) {
241
+
242
  // The 'G' modifier is available since PHP 5.1.0
243
  case 'g':
244
+
245
  $val *= 1024;
246
+
247
  case 'm':
248
+
249
  $val *= 1024;
250
+
251
  case 'k':
252
+
253
  $val *= 1024;
254
+
255
  }
256
 
257
  return $val;
259
 
260
 
261
  /**
262
+ * Sanitize data
263
+ *
264
+ * @since 1.2.8
265
+ * @return string
266
  */
267
+ protected function sanitize( $value )
268
  {
269
 
270
+ // emove line breaks ##
271
  $value = str_replace("\r", '', $value);
272
  $value = str_replace("\n", '', $value);
273
  $value = str_replace("\t", '', $value);
274
+
275
+ // with wp_kses ##
276
+ $value = wp_kses( $value, $this->get_allowed_tags() );
277
+
278
+ // with esc_html
279
+ $value = esc_html( $value );
280
+
281
+ // return value ##
282
  return $value;
283
 
284
  }
285
 
286
+
287
+ /**
288
+ * Get allowed tags for wp_kses
289
+ *
290
+ * @since 1.2.8
291
+ * @return Array
292
+ */
293
+ protected function get_allowed_tags()
294
+ {
295
+
296
+ $allowed_tags = array(
297
+ 'a' => array(
298
+ 'href' => array(),
299
+ 'title' => array()
300
+ ),
301
+ 'br' => array(),
302
+ 'em' => array(),
303
+ 'strong' => array(),
304
+ );
305
+
306
+ return apply_filters( 'export_user_data_allowed_tags', $allowed_tags );
307
+
308
+ }
309
+
310
+
311
+
312
+ /**
313
+ * Load up saved exports for this user
314
+ * Set to public as hooked into action
315
+ *
316
+ * @since 0.9.6
317
+ * @return Array of saved exports
318
+ */
319
+ public function load_buddypress()
320
+ {
321
+
322
+ // do we have a bp object in the globals ##
323
+ if (
324
+ is_plugin_active( 'buddypress/bp-loader.php' ) // plugin active
325
+ && function_exists ( 'buddypress' ) // loader function exists ##
326
+ && ! isset( $GLOBALS['bp'] ) // but global unavailble ##
327
+ ) {
328
+
329
+ $this->log( 'BP not loaded - calling buddpress()' );
330
+
331
+ // call BP
332
+ buddypress();
333
+
334
+ return true;
335
+
336
+ }
337
+
338
+ #$this->log( 'BP loaded' );
339
+
340
+ return true;
341
+
342
+ }
343
+
344
+
345
  /**
346
  * Load up saved exports for this user
347
+ * Set to public as hooked into action
348
  *
349
  * @since 0.9.6
350
  * @return Array of saved exports
351
  */
352
  public function load_user_options()
353
  {
354
+
355
+
356
+ $this->q_eud_exports =
357
+ get_user_meta( get_current_user_id(), 'q_eud_exports' ) ?
358
+ get_user_meta( get_current_user_id(), 'q_eud_exports', true ) :
359
+ array() ;
360
  #var_dump( $this->q_eud_exports );
361
+
362
  }
363
+
364
+
365
  /**
366
  * Get list of saved exports for this user
367
  *
368
  * @since 0.9.4
369
  * @return Array of saved exports
370
  */
371
+ protected function get_user_options()
372
  {
373
+
374
  // get the stored options - filter empty array items ##
375
  $q_eud_exports = array_filter( $this->q_eud_exports );
376
+
377
  // quick check if the array is empty ##
378
+ if ( empty ( $q_eud_exports ) ) {
379
+
380
+ return false;
381
+
382
  }
383
+
384
  // test the array of saved exports ##
385
  #$this->pr( $q_eud_exports );
386
+
387
  // start with an empty array ##
388
  $exports = array();
389
+
390
  // loop over each saved export and grab each key ##
391
  foreach ( $q_eud_exports as $key => $value ) {
392
+
393
  $exports[] = $key;
394
+
395
  }
396
+
397
  // kick back array ##
398
  return( $exports );
399
+
400
  }
401
+
402
+
403
  /**
404
  * Check for and load stored user options
405
+ *
406
  * @since 0.9.3
407
  * @return void
408
  */
409
+ protected function get_user_options_by_export( $export = null )
410
  {
411
+
412
  // sanity check ##
413
  if ( is_null ( $export ) ) { return false; }
414
+
415
  if ( isset( $this->q_eud_exports[$export] ) ) {
416
 
417
  $this->usermeta_saved_fields = $this->q_eud_exports[$export]['usermeta_saved_fields'];
418
  $this->bp_fields_saved_fields = $this->q_eud_exports[$export]['bp_fields_saved_fields'];
419
  $this->bp_fields_update_time_saved_fields = $this->q_eud_exports[$export]['bp_fields_update_time_saved_fields'];
420
+ $this->updated_since_date = isset( $this->q_eud_exports[$export]['updated_since_date'] ) ? $this->q_eud_exports[$export]['updated_since_date'] : null ;
421
+ $this->field_updated_since = isset( $this->q_eud_exports[$export]['field_updated_since'] ) ? $this->q_eud_exports[$export]['field_updated_since'] : null ;
422
  $this->role = $this->q_eud_exports[$export]['role'];
423
  $this->roles = $this->q_eud_exports[$export]['roles'];
424
  $this->groups = $this->q_eud_exports[$export]['groups'];
425
+ $this->user_fields = isset( $this->q_eud_exports[$export]['user_fields'] ) ? $this->q_eud_exports[$export]['user_fields'] : null ;
426
  $this->start_date = $this->q_eud_exports[$export]['start_date'];
427
  $this->end_date = $this->q_eud_exports[$export]['end_date'];
428
  $this->limit_offset = $this->q_eud_exports[$export]['limit_offset'];
445
  $this->limit_offset = '';
446
  $this->limit_total = '';
447
  $this->format = '';
448
+
449
  }
450
+
451
  }
452
+
453
 
454
  /**
455
+ * Method to store user options
456
  *
457
  * @param string $save_export Export Key name
458
  * @param array $save_options Array of export options to save
459
  * @since 0.9.3
460
  * @return void
461
  */
462
+ protected function set_user_options( $key = null, $options = null )
463
  {
464
+
465
  // sanity check ##
466
  if ( is_null ( $key ) || is_null ( $options ) ) {
467
+
468
  #$this->pr( 'missing save values' );
469
  return false;
470
+
471
  }
472
+
473
  #$this->pr( $key );
474
  #$this->pr( $options );
475
+
476
  // for now, I'm simply allowing keys to be resaved - but this is not so logical ##
477
+ if ( array_key_exists( $key, $this->q_eud_exports ) ) {
478
+
479
  #$this->pr( 'key exists, skipping save' );
480
  #return false;
481
+
482
  }
483
+
484
  if ( isset( $options ) && is_array( $options ) ) {
485
+
486
  // update_option sanitizes the option name but not the option value ##
487
  foreach ( $options as $field_name => $field_value ) {
488
 
502
  }
503
 
504
  }
505
+
506
  // assign the sanitized array of values to the class property $q_eud_exports as a new array with key $key ##
507
  $this->q_eud_exports[$key] = $options;
508
+
509
  // update stored user_meta values, if previous key found ##
510
  if ( get_user_meta( get_current_user_id(), 'q_eud_exports' ) !== false ) {
511
+
512
  #update_option( 'q_eud_exports', $this->q_eud_exports );
513
  update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
514
+
515
  // create new user meta key ##
516
  } else {
517
+
518
  #add_option( 'q_eud_exports', $this->q_eud_exports, $deprecated, $autoload );
519
  add_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
520
+
521
  }
522
+
523
  }
524
+
525
+ }
526
+
527
+
528
  /**
529
  * method to delete user options
530
  *
532
  * @since 0.9.3
533
  * @return void
534
  */
535
+ protected function delete_user_options( $key = null )
536
  {
537
+
538
  // sanity check ##
539
  if ( is_null ( $key ) || ! array_key_exists( $key, $this->q_eud_exports ) ) { return false; }
540
+
541
  // clean it up ##
542
  $key = sanitize_text_field( $key );
543
+
544
  // check it out ##
545
  #$this->pr( $key );
546
+
547
  // drop the array by it's key name from the class property ##
548
  unset( $this->q_eud_exports[$key] );
549
+
550
  // update the saved data ##
551
  update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
552
+
553
  }
554
+
555
+
556
  /**
557
  * Copy of BP_XProfile_ProfileData::get_all_for_user() from BP version 2.0?
558
  * Get all of the profile information for a specific user.
559
+ *
560
  * @param $user_id Integer ID of specific user
561
  * @since 0.9.6
562
  * @return Array User profile fields
563
  * @deprecated since 1.2.1
564
  */
565
+ protected function get_all_for_user( $user_id = null )
566
  {
567
+
568
  // sanity check ##
569
  if ( is_null( $user_id ) ) { return false; }
570
+
571
  global $wpdb, $bp;
572
+
573
  $bp = buddypress();
574
 
575
+ $results = $wpdb->get_results(
576
+ $wpdb->prepare(
577
  "
578
+ 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
579
+ FROM {$bp->profile->table_name_groups} g
580
+ LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id
581
+ 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
582
  WHERE d.user_id = %d AND d.value != ''
583
  "
584
+ , $user_id
585
+ )
586
  );
587
+
588
  $profile_data = array();
589
 
590
  if ( ! empty( $results ) ) {
591
+
592
  $profile_data['user_login'] = $results[0]->user_login;
593
  $profile_data['user_nicename'] = $results[0]->user_nicename;
594
  $profile_data['user_email'] = $results[0]->user_email;
595
 
596
  foreach( (array) $results as $field ) {
597
+
598
  $profile_data[$field->field_name] = array(
599
  'field_group_id' => $field->field_group_id,
600
  'field_group_name' => $field->field_group_name,
602
  'field_type' => $field->field_type,
603
  'field_data' => $field->field_data
604
  );
605
+
606
  }
607
+
608
  }
609
 
610
  return $profile_data;
611
+
612
  }
613
+
614
+
615
  /**
616
+ * Attempt to generate the export file based on the passed arguements
617
  *
618
  * @since 0.1
619
+ * @return Mixes
620
  **/
621
+ public function generate_data()
622
  {
623
+
624
  // Check if the user clicked on the Save, Load, or Delete Settings buttons ##
625
+ if (
626
  ! isset( $_POST['_wpnonce-q-eud-export-user-page_export'] )
627
  || isset( $_POST['load_export'] )
628
  || isset( $_POST['save_export'] )
629
+ || isset( $_POST['delete_export'] ) )
630
  {
631
 
632
  return false;
633
 
634
  }
635
+
636
+ // Increase maximum execution time to prevent "Maximum execution time exceeded" error ##
637
+ ini_set( 'max_execution_time', -1 );
638
+ ini_set( 'memory_limit', -1 ); // looks like a bad idea ##
639
+
640
  // check admin referer ##
641
  check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' );
642
+
643
  // build argument array ##
644
  $args = array(
645
  'fields' => ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) ? 'all' : array( 'ID' ), // exclude standard wp_users fields from get_users query ##
657
 
658
  // is there a range limit in place for the export ? ##
659
  if ( isset( $_POST['limit_total'] ) && $_POST['limit_total'] != '' ) {
660
+
661
  // let's just make sure they are integer values ##
662
  $limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
663
  $limit_total = (int)$_POST['limit_total'];
664
+
665
  if ( is_int( $limit_offset ) && is_int( $limit_total ) ) {
666
+
667
  $args['offset'] = $limit_offset;
668
+ $args['number'] = $limit_total; // number - Limit the total number of users returned ##
669
+
670
  // test it ##
671
  #wp_die( $this->pr( $args ) );
672
+
673
  }
674
+
675
  }
676
+
677
  // pre_user query ##
678
  add_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
679
  $users = get_users( $args );
680
  remove_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
681
+
682
  // test args ##
683
  #wp_die( $this->pr ( $users ) );
684
+
685
  // no users found, so chuck an error into the args array and exit the export ##
686
  if ( ! $users ) {
687
 
689
  exit;
690
 
691
  }
692
+
693
  // get sitename and clean it up ##
694
  $sitename = sanitize_key( get_bloginfo( 'name' ) );
695
  if ( ! empty( $sitename ) ) {
741
  // to xls ##
742
  header( 'Content-Description: File Transfer' );
743
  header("Content-Type: application/vnd.ms-excel");
744
+ header("Content-Disposition: attachment; filename=$filename.xls");
745
+ header("Pragma: no-cache");
746
  header("Expires: 0");
747
 
748
  // set a csv check flag
775
  $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
776
  #$this->pr( $usermeta );
777
  $usermeta_fields = array();
778
+
779
  if ( $usermeta && is_array( $usermeta ) ) {
780
  foreach( $usermeta as $field ) {
781
  $usermeta_fields[] = sanitize_text_field ( $field );
782
  }
783
  }
784
+
785
  #$this->pr( $usermeta_fields );
786
  #exit;
787
 
823
  global $wpdb;
824
 
825
  // debug ##
826
+ #$this->log( 'merging array' );
827
+
828
  // compile final fields list ##
829
+ $fields = array_merge(
830
+ $this->get_user_fields() // standard wp_user fields ##
831
+ , $this->get_special_fields() // 'special' fields - which are controlled via dedicated checks ##
832
  , $usermeta_fields // wp_user_meta fields ##
833
  , $bp_fields_passed // selected buddypress fields ##
834
  , $bp_fields_update_passed // update date for buddypress fields ##
835
  );
836
+
837
  // test field array ##
838
+ #$this->pr( $fields );
839
+
840
  // build the document headers ##
841
  $headers = array();
842
+
843
  foreach ( $fields as $key => $field ) {
844
 
845
+ #$this->log( 'Field: '. $field );
846
+
847
  // rename programs field ##
848
  if ( $field == 'member_of_club' ){
849
  $field = 'Program';
850
  }
851
+
852
+ // grab fields to exclude from exports ##
853
+ if ( in_array( $fields[$key], $this->get_exclude_fields() ) ) {
854
+
855
+ #$this->log( 'Dump Field: '. $fields[$key] );
856
 
857
  // ditch 'em ##
858
  unset( $fields[$key] );
873
  }
874
 
875
  }
876
+
877
  // quick check ##
878
+ #$this->log( $fields );
879
+ #if ( $this->debug ) $this->log( '$bp_fields_passed: '. var_dump( $bp_fields_passed ) );
880
+
881
  // no more buffering while spitting back the export data ##
882
  ob_end_flush();
883
+
884
  // get the value in bytes allocated for Memory via php.ini ##
885
  // @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
886
  $memory_limit = $this->return_bytes( ini_get('memory_limit') ) * .75;
887
+
888
  // we need to disable caching while exporting because we export so much data that it could blow the memory cache
889
  // if we can't override the cache here, we'll have to clear it later...
890
  if ( function_exists( 'override_function' ) ) {
891
+
892
  override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
893
  override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
894
  override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
895
  override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
896
+
897
  } elseif ( function_exists( 'runkit_function_redefine' ) ) {
898
+
899
  runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
900
  runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
901
  runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
908
 
909
  // echo headers ##
910
  echo $pre . implode( $seperator, $headers ) . $breaker;
911
+
912
+ #wp_die( $this->pr( $users ) );
913
+
914
  // build row values for each user ##
915
  foreach ( $users as $user ) {
916
+
917
+ #wp_die( $this->pr( $user ) );
918
+
919
  // check if we're hitting any Memory limits, if so flush them out ##
920
  // per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
921
  if ( memory_get_usage( true ) > $memory_limit ) {
924
 
925
  // open up a new empty array ##
926
  $data = array();
927
+
 
 
928
  // BP loaded ? ##
929
+ if (
930
+ ! $this->bp_data_available
931
+ && function_exists ( 'bp_is_active' )
932
+ && bp_is_active( 'xprofile' )
933
+ && class_exists( 'BP_XProfile_ProfileData' )
934
+ && method_exists( 'BP_XProfile_ProfileData', 'get_all_for_user' )
935
+ && is_callable ( array( 'BP_XProfile_ProfileData', 'get_all_for_user' ) )
936
+ ) {
937
+
938
+ $this->log( 'XProfile Accessible' );
939
+ $this->bp_data_available = true; // we only need to check for BP once ##
940
+
941
+ }
942
+
943
+ // grab all user data ##
944
+ if (
945
+ $this->bp_data_available
946
+ && ! $bp_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID )
947
+ ) {
948
+
949
+ // null the data to be sure ##
950
+ $bp_data = false;
951
+
952
+ $this->log( 'XProfile returned no data ID#: '.$user->ID );
953
+
954
  }
955
+
956
  // single query method - get all user_meta data ##
957
  $get_user_meta = (array)get_user_meta( $user->ID );
958
+ #wp_die( $this->pr( $get_user_meta ) );
959
+
960
  // Filter out empty meta data ##
961
  #$get_user_meta = array_filter( array_map( function( $a ) {
962
  # return $a[0];
963
  #}, $get_user_meta ) );
964
+
965
  // loop over each field ##
966
  foreach ( $fields as $field ) {
967
+
968
  // check if this is a BP field ##
969
+ if ( isset( $bp_data ) && isset( $bp_data[$field] ) && in_array( $field, $bp_fields_passed ) )
970
  {
971
+
972
  // old way from single BP query ##
973
  $value = $bp_data[$field];
974
+
975
  if ( is_array( $value ) ) {
976
+
977
  $value = maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
978
  #$value = $value['field_data'];
979
+
980
  /**
981
  * cwjordan
982
+ * after unserializing it we then
983
+ * need to implode it so
984
  * that we have something readable?
985
  * Going to use :: as a separator
986
  * because that's what Buddypress Members Import
987
+ * expects, but we might want to make that
988
+ * configurable.
989
  */
990
  if ( is_array( $value ) ) {
991
+ $value = implode("::", $value );
992
  }
993
 
994
  }
995
+
996
+ // sanitize ##
997
+ #$value = $this->sanitize($value);
998
 
999
  // check if this is a BP field we want the updated date for ##
1000
+ }
1001
+ elseif ( in_array( $field, $bp_fields_update_passed ) )
1002
  {
1003
 
1004
  global $bp;
1006
  $real_field = str_replace(" Update Date", "", $field);
1007
  $field_id = xprofile_get_field_id_from_name( $real_field );
1008
  $value = $wpdb->get_var (
1009
+ $wpdb->prepare(
1010
  "
1011
+ SELECT last_updated
1012
+ FROM {$bp->profile->table_name_data}
1013
  WHERE user_id = %d AND field_id = %d
1014
  "
1015
  , $user->ID
1016
+ , $field_id
1017
+ )
1018
  );
1019
 
1020
  // include the user's role in the export ##
1021
+ }
1022
  elseif ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] && $field == 'roles' )
1023
  {
1024
+
1025
  // add "Role" as $value ##
1026
  $value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
1027
+
1028
  // include the user's BP group in the export ##
1029
+ }
1030
+ elseif ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] && $field == 'groups' )
1031
  {
1032
+
1033
  if ( function_exists( 'groups_get_user_groups' ) ) {
1034
+
1035
  // check if user is a member of any groups ##
1036
  $group_ids = groups_get_user_groups( $user->ID );
1037
+
1038
+ #$this->pr( $group_ids );
1039
  #wp_die( pr( 'loaded group data.' ));
 
 
1040
 
1041
+ if ( ! $group_ids || $group_ids == '' ) {
1042
+
1043
+ $value = '';
1044
 
1045
  } else {
1046
 
1048
  $groups = array();
1049
 
1050
  // loop over all groups ##
1051
+ foreach( $group_ids["groups"] as $group_id ) {
1052
 
1053
+ $groups[] = groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
1054
 
1055
  }
1056
 
1060
  }
1061
 
1062
  } else {
1063
+
1064
  $value = '';
1065
+
1066
  }
1067
+
1068
+ }
1069
+ elseif ( $field == 'bp_latest_update' || $field == 'last_activity' )
1070
  {
1071
+
1072
  // https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
1073
  $value = bp_get_user_last_activity( $user->ID );
1074
+
1075
  // user or usermeta field ##
1076
+ }
1077
+ else
1078
+ {
1079
+
1080
  // the user_meta key isset ##
1081
  if ( isset( $get_user_meta[$field] ) ) {
1082
+
1083
  // take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
1084
  $value = $get_user_meta[$field][0];
1085
+
1086
  // standard WP_User value ##
1087
  } else {
1088
+
1089
  // use the magically assigned value from WP_Users
1090
+ $value =isset( $user->{$field} ) ? $user->{$field} : null ;
1091
+
1092
  }
1093
+
1094
+
1095
  // the $value might be serialized ##
1096
+ $value = $this->unserialize( $value );
1097
+
1098
+ // the value is an array ##
1099
  if ( is_array ( $value ) ) {
1100
 
1101
  // recursive implode it ##
1102
+ $value = $this->recursive_implode( $value );
1103
 
1104
  }
1105
+
1106
+ // sanitize ##
1107
+ #$value = $this->sanitize($value);
1108
+
1109
  }
1110
+
1111
+
1112
  // correct program value to Program Name ##
1113
  if ( $field == 'member_of_club' ) {
1114
+
1115
  $value = get_the_title($value);
1116
+
1117
  }
1118
+
1119
+ // sanitize ##
1120
+ $value = $this->sanitize($value);
1121
+
1122
  // wrap values in quotes and add to array ##
1123
  if ( $is_csv ) {
1124
+
1125
+ $data[] = '"' . str_replace( '"', '""', $this->special_characters( $value ) ) . '"';
1126
+
1127
  // just add to array ##
1128
  } else {
1129
+
1130
+ $data[] = $this->special_characters( $value );
1131
  }
1132
 
1133
  }
1137
 
1138
  }
1139
 
1140
+ // close doc wrapper..
1141
  echo $doc_end;
1142
 
1143
  // stop PHP, so file can export correctly ##
1145
 
1146
  }
1147
 
1148
+
1149
  /**
1150
  * Content of the settings page
1151
  *
1152
  * @since 0.1
1153
  **/
1154
+ public function users_page()
1155
  {
1156
 
1157
  // quick security check ##
1158
  if ( ! current_user_can( 'list_users' ) ) {
1159
+
1160
  wp_die( __( 'You do not have sufficient permissions to access this page.', 'export-user-data' ) );
1161
+
1162
  }
1163
+
1164
  // Save settings button was pressed ##
1165
+ if (
1166
+ isset( $_POST['save_export'] )
1167
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1168
  ) {
1169
+
1170
  // start with an empty variable ##
1171
  $save_export = "";
1172
+
1173
  if ( ! empty( $_POST['save_new_export_name'] ) ) {
1174
+
1175
  // assign value ##
1176
  $save_export = $_POST['save_new_export_name'];
1177
+
1178
  } elseif ( ! empty( $_POST['export_name'] ) ) {
1179
+
1180
  $save_export = $_POST['export_name'];
1181
+
1182
  }
1183
 
1184
  // clean up $save_export ##
1185
  $save_export = sanitize_text_field( $save_export );
1186
+
1187
  // Build array of $options to save and save them ##
1188
  if ( isset( $save_export ) ) {
1189
+
1190
  // prepare all array values ##
1191
  $usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
1192
  $bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
1202
  $limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
1203
  $updated_since_date = isset ( $_POST['updated_since_date'] ) ? $_POST['updated_since_date'] : '' ;
1204
  $field_updated_since = isset ( $_POST['bp_field_updated_since'] ) ? $_POST['bp_field_updated_since'] : '';
1205
+
1206
  // assign all values to an array ##
1207
  $save_array = array (
1208
  'usermeta_saved_fields' => $usermeta,
1218
  'limit_total' => $limit_total,
1219
  'updated_since_date' => $updated_since_date,
1220
  'field_updated_since' => $field_updated_since,
1221
+ 'format' => $format
1222
  );
1223
+
1224
  // store the options, for next load ##
1225
  $this->set_user_options( $save_export, $save_array );
1226
+
1227
  // Display the settings the user just saved instead of blanking the form ##
1228
  $_POST['load_export'] = 'Load Settings';
1229
  $_POST['export_name'] = $save_export;
1230
+
1231
  }
1232
+
1233
  }
1234
 
1235
  // Load settings button was pressed ( or option saved and $_POST variables hijacked )##
1236
+ if (
1237
+ isset( $_POST['load_export'] )
1238
+ && isset( $_POST['export_name'] )
1239
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1240
  ) {
1241
+
1242
  $this->get_user_options_by_export( sanitize_text_field( $_POST['export_name'] ) );
1243
+
1244
  }
1245
+
1246
  // Delete settings button was pressed ##
1247
+ if (
1248
+ isset( $_POST['delete_export'] )
1249
+ && isset( $_POST['export_name'] )
1250
+ && check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
1251
  ) {
1252
+
1253
  $this->delete_user_options( sanitize_text_field( $_POST['export_name'] ) );
1254
+
1255
  }
1256
+
1257
  // what's in 'this' ? ##
1258
  #self:pr( $this );
1259
+
1260
  ?>
1261
  <div class="wrap">
1262
  <h2><?php _e( 'Export User Data', 'export-user-data' ); ?></h2>
1312
  $meta_keys_system = apply_filters( 'export_user_data_meta_keys_system', $meta_keys_system );
1313
 
1314
  // test array ##
1315
+ #echo '<pre>'; var_dump($meta_keys); echo '</pre>';
1316
 
1317
  // check if we got anything ? ##
1318
  if ( $meta_keys ) {
1374
  }
1375
  ?>
1376
  </select>
1377
+ <p class="description"><?php
1378
+ printf(
1379
  __( 'Select the user meta keys to export, use the filters to simplify the list.', 'export-user-data' )
1380
+ );
1381
  ?></p>
1382
  </td>
1383
  </tr>
1398
  $bp_fields = wp_list_pluck( $bp_fields, 'name' );
1399
 
1400
  // test array ##
1401
+ #echo '<pre>'; var_dump($bp_fields); echo '</pre>';
1402
 
1403
  // allow array to be filtered ##
1404
  $bp_fields = apply_filters( 'export_user_data_bp_fields', $bp_fields );
1429
 
1430
  ?>
1431
  </select>
1432
+ <p class="description"><?php
1433
+ printf(
1434
  __( 'Select the BuddyPress XProfile keys to export', 'export-user-data' )
1435
+ );
1436
  ?></p>
1437
  </td>
1438
  </tr>
1460
 
1461
  ?>
1462
  </select>
1463
+ <p class="description"><?php
1464
+ printf(
1465
  __( 'Select the BuddyPress XProfile keys updated dates to export', 'export-user-data' )
1466
+ );
1467
  ?></p>
1468
  </td>
1469
  </tr>
1470
+
1471
  <tr valign="top" class="toggleable">
1472
  <th scope="row"><label for="groups"><?php _e( 'BP User Groups', 'export-user-data' ); ?></label></th>
1473
  <td>
1474
  <input id='groups' type='checkbox' name='groups' value='1' <?php checked( isset ( $this->groups ) ? intval ( $this->groups ) : '', 1 ); ?> />
1475
+ <p class="description"><?php
1476
+ printf(
1477
  __( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1478
  , esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
1479
  , 'Codex'
1480
+ );
1481
  ?></p>
1482
  </td>
1483
  </tr>
1484
+ <?php
1485
 
1486
  } // BP installed and active ##
1487
 
1490
  <th scope="row"><label for="user_fields"><?php _e( 'Standard User Fields', 'export-user-data' ); ?></label></th>
1491
  <td>
1492
  <input id='user_fields' type='checkbox' name='user_fields' value='1' <?php checked( isset ( $this->user_fields ) ? intval ( $this->user_fields ) : '', 1 ); ?> />
1493
+ <p class="description"><?php
1494
+
1495
+ #$this->log( 'user_fields: '.$this->user_fields );
1496
+ #echo 'user_fields: '. $this->user_fields;
1497
+
1498
+ printf(
 
 
 
 
1499
  __( 'Include Standard user profile fields, such as user_login. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1500
  , esc_html('https://codex.wordpress.org/Database_Description#Table:_wp_users')
1501
  , 'Codex'
1502
+ );
1503
+
1504
  ?></p>
1505
  </td>
1506
  </tr>
1507
+
1508
  <tr valign="top" class="toggleable">
1509
  <th scope="row"><label for="q_eud_users_role"><?php _e( 'Role', 'export-user-data' ); ?></label></th>
1510
  <td>
1513
 
1514
  echo '<option value="">' . __( 'All Roles', 'export-user-data' ) . '</option>';
1515
  global $wp_roles;
1516
+
1517
  foreach ( $wp_roles->role_names as $role => $name ) {
1518
+
1519
  if ( isset ( $this->role ) && ( $this->role == $role ) ) {
1520
+
1521
  echo "\n\t<option selected value='" . esc_attr( $role ) . "'>$name</option>";
1522
+
1523
  } else {
1524
+
1525
  echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
1526
+
1527
  }
1528
  }
1529
 
1530
 
1531
  ?>
1532
  </select>
1533
+ <p class="description"><?php
1534
+ printf(
1535
  __( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1536
  , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1537
  , 'Codex'
1538
+ );
1539
  ?></p>
1540
  </td>
1541
  </tr>
1542
+
1543
  <tr valign="top" class="toggleable">
1544
  <th scope="row"><label for="roles"><?php _e( 'User Roles', 'export-user-data' ); ?></label></th>
1545
  <td>
1546
  <input id='roles' type='checkbox' name='roles' value='1' <?php checked( isset ( $this->roles ) ? intval ( $this->roles ) : '', 1 ); ?> />
1547
+ <p class="description"><?php
1548
+ printf(
1549
  __( 'Include all of the users <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1550
  , esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
1551
  , 'Roles'
1552
+ );
1553
  ?></p>
1554
  </td>
1555
  </tr>
1569
 
1570
  $clubs_array = get_posts(array( 'post_type'=> 'club', 'posts_per_page' => -1 )); // grab all posts of type "club" ##
1571
 
1572
+ foreach ( $clubs_array as $c ) { // loop over all clubs ##
1573
 
1574
  #$clubs[$c->ID] = $c; // grab club ID ##
1575
  echo "\n\t<option value='" . esc_attr( $c->ID ) . "'>$c->post_title</option>";
1590
  <td>
1591
  <input type="text" id="q_eud_users_start_date" name="start_date" value="<?php echo $this->start_date; ?>" class="start-datepicker" />
1592
  <input type="text" id="q_eud_users_end_date" name="end_date" value="<?php echo $this->end_date; ?>" class="end-datepicker" />
1593
+ <p class="description"><?php
1594
+ printf(
1595
  __( 'Pick a start and end user registration date to limit the results.', 'export-user-data' )
1596
+ );
1597
  ?></p>
1598
  </td>
1599
  </tr>
1600
+
1601
  <tr valign="top" class="toggleable">
1602
  <th scope="row"><label><?php _e( 'Limit Range', 'export-user-data' ); ?></label></th>
1603
  <td>
1604
  <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' ); ?>">
1605
  <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' ); ?>">
1606
+ <p class="description"><?php
1607
+ printf(
1608
  __( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
1609
  , esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
1610
  , 'Codex'
1611
+ );
1612
  ?></p>
1613
  </td>
1614
  </tr>
1631
  ?>
1632
  </select>
1633
 
1634
+ <p class="description"><?php
1635
+ printf(
1636
  __( 'Limit the results to users who have updated this extended profile field after this date.', 'export-user-data' )
1637
+ );
1638
  ?></p>
1639
  </td>
1640
  </tr>
1656
  }
1657
  ?>
1658
  </select>
1659
+ <p class="description"><?php
1660
+ printf(
1661
  __( 'Select the format for the export file.', 'export-user-data' )
1662
+ );
1663
  ?></p>
1664
  </td>
1665
  </tr>
1666
+
1667
  <tr valign="top" class="remember">
1668
  <th scope="row"><label for="q_eud_save_options"><?php _e( 'Stored Options', 'export-user-data' ); ?></label></th>
1669
  <td>
1680
  ?>
1681
  <div class="row">
1682
  <select name="export_name" id="q_eud_save_options" class="regular-text">
1683
+ <?php
1684
 
1685
  // loop over each saved export ##
1686
  foreach( $this->get_user_options() as $export ) {
1687
 
1688
  // select Loaded export name, if selected ##
1689
+ if (
1690
+ isset( $_POST['load_export'] )
1691
+ && isset( $_POST['export_name'] )
1692
+ && ( $_POST['export_name'] == $export )
1693
  ) {
1694
 
1695
  echo "<option selected value='$export'>$export</option>";
1702
  }
1703
 
1704
  }
1705
+
1706
  ?>
1707
  </select>
1708
 
1712
 
1713
  }
1714
 
1715
+ ?>
1716
  </div>
1717
  <p class="description"><?php _e( 'Save, load or delete your stored export options.', 'export-user-data' ); ?></p>
1718
+
1719
  </td>
1720
  </tr>
1721
+
1722
  <tr valign="top">
1723
  <th scope="row">
1724
  <label for="q_eud_xprofile"><?php _e( 'Advanced Options', 'export-user-data' ); ?></label>
1729
  </div>
1730
  </td>
1731
  </tr>
1732
+
1733
  </table>
1734
  <p class="submit">
1735
  <input type="hidden" name="_wp_http_referer" value="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" />
1737
  </p>
1738
  </form>
1739
  </div>
1740
+
1741
  <?php
1742
  }
1743
 
1744
+
1745
  /**
1746
  * Inline jQuery
1747
  * @since 0.8.2
1748
  */
1749
+ public function jquery()
1750
  {
1751
 
1752
+ // load the scripts on only the plugin admin page
1753
  if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
1754
+
1755
  ?>
1756
  <script>
1757
+
1758
  // lazy load in some jQuery validation ##
1759
  jQuery(document).ready(function($) {
1760
 
1761
  // build super multiselect ##
1762
  jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
1763
+
1764
  //Select any fields from saved settings ##
1765
+ jQuery('#usermeta').multiSelect('select',([<?php echo( $this->quote_array( $this->usermeta_saved_fields ) ); ?>]));
1766
+ jQuery('#bp_fields').multiSelect('select',([<?php echo( $this->quote_array($this->bp_fields_saved_fields ) ); ?>]));
1767
+ jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( $this->quote_array( $this->bp_fields_update_time_saved_fields ) ); ?>]));
1768
 
1769
  // show only common ##
1770
  jQuery('.usermeta-common').click(function(e){
1783
  e.preventDefault();
1784
  jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
1785
  });
1786
+
1787
  // select none ##
1788
  jQuery('.select-none').click(function(e){
1789
  e.preventDefault();
1810
  }
1811
 
1812
  });
1813
+
1814
  // toggle advanced options ##
1815
  jQuery(".toggle a").click( function(e) {
1816
  e.preventDefault();
1822
  jQuery(this).text("<?php _e( 'Show', 'export-user-data' ); ?>");
1823
  }
1824
  });
1825
+
1826
  // validate save button ##
1827
  jQuery("#save_export").click( function(e) {
1828
+
1829
  // grab the value of the input ##
1830
  var q_eud_save_options_new_export = jQuery('#q_eud_save_options_new_export').val();
1831
+
1832
  if ( ! q_eud_save_options_new_export || q_eud_save_options_new_export == '' ) {
1833
+
1834
  e.preventDefault(); // stop things here ##
1835
  jQuery('#q_eud_save_options_new_export').addClass("error");
1836
+
1837
  }
1838
+
1839
  });
1840
+
1841
  // remove validation on focus ##
1842
  jQuery("body").on( 'focus', '#q_eud_save_options_new_export', function(e) {
1843
+
1844
  jQuery(this).removeClass("error");
1845
+
1846
  });
1847
+
1848
+ <?php
1849
+
1850
  // method returns an object with "first" & "last" keys ##
1851
+ $dates = $this->get_user_registered_dates();
1852
+
1853
+ // get date format from WP settings #
1854
+ $date_format = 'yy-mm-dd' ; // get_option('date_format') ? get_option('date_format') : 'yy-mm-dd' ;
1855
+ $start_of_week = get_option('start_of_week') ? get_option('start_of_week') : 'yy-mm-dd' ;
1856
+ #$this->log( 'Date format: '.$date_format );
1857
+
1858
  ?>
1859
+
1860
  // start date picker ##
1861
  jQuery('.start-datepicker').datepicker( {
1862
+ dateFormat : '<?php echo $date_format; ?>',
1863
  minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1864
+ maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
1865
+ firstDay : '<?php echo $start_of_week; ?>'
1866
  } );
1867
+
1868
  // end date picker ##
1869
  jQuery('.end-datepicker').datepicker( {
1870
+ dateFormat : '<?php echo $date_format; ?>',
1871
  minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1872
+ maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
1873
+ firstDay : '<?php echo $start_of_week; ?>'
1874
  } );
1875
+
1876
  // end date picker ##
1877
  // might want to set minDate to something else, but not sure
1878
  // what would be best for everyone
1879
+ jQuery('.updated-datepicker').datepicker( {
1880
+ dateFormat : '<?php echo $date_format; ?>',
1881
+ minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
1882
+ maxDate : '0',
1883
+ firstDay : '<?php echo $start_of_week; ?>'
1884
+ } );
1885
+
1886
  });
1887
 
1888
  </script>
1890
  }
1891
 
1892
  }
1893
+
1894
+
1895
+ /**
1896
  * Inline CSS
1897
  * @since 0.8.2
1898
  */
1899
+ public function css()
1900
  {
1901
 
1902
+ // load the scripts on only the plugin admin page
1903
  if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
1904
  ?>
1905
  <style>
1910
  }
1911
 
1912
  }
1913
+
1914
+
1915
  /**
1916
  * Data to exclude from export
1917
  */
1918
+ protected function get_exclude_fields()
1919
  {
1920
+
1921
  $exclude_fields = array (
1922
  'user_pass'
1923
+ , 'q_eud_exports'
1924
  #, 'user_activation_key'
1925
  );
1926
+
1927
  return apply_filters( 'export_user_data_exclude_fields', $exclude_fields );
1928
 
1929
  }
1930
+
1931
+
1932
  /**
1933
  * Get the array of standard WP_User fields to return
1934
  */
1935
+ protected function get_user_fields()
1936
  {
1937
+
1938
  // standard wp_users fields ##
1939
  if ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) {
1940
+
1941
  // debug ##
1942
+ #$this->log( 'full' );
1943
+
1944
  // exportable user data ##
1945
  $user_fields = array(
1946
  'ID'
1954
  , 'user_status'
1955
  , 'display_name'
1956
  );
1957
+
1958
  } else {
1959
+
1960
  // debug ##
1961
+ #$this->log( 'reduced' );
1962
+
1963
+ // just return the user ID
1964
  $user_fields = array(
1965
  'ID'
1966
  );
1967
+
1968
  }
1969
+
1970
  // kick back values ##
1971
  return apply_filters( 'export_user_data_user_fields', $user_fields );
1972
 
1973
  }
1974
+
1975
+
1976
  /**
1977
  * Get the array of special user fields to return
1978
  */
1979
+ protected function get_special_fields()
1980
  {
1981
+
1982
  // exportable user data ##
1983
  $special_fields = array(
1984
  # 'roles' // list of WP Roles
1985
  #, 'groups' // BP Groups
1986
  );
1987
+
1988
  // should we allow groups ##
1989
  if ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] ) {
1990
+
1991
  $special_fields[] = 'groups'; // add groups ##
1992
+
1993
  }
1994
+
1995
  // should we allow groups ##
1996
  if ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] ) {
1997
+
1998
  $special_fields[] = 'roles'; // add groups ##
1999
+
2000
  }
2001
+
2002
  // kick back the array ##
2003
  return apply_filters( 'export_user_data_special_fields', $special_fields );
2004
 
2005
  }
2006
+
2007
+
2008
  /*
2009
  * Pre User Query
2010
  */
2011
+ public function pre_user_query( $user_search )
2012
  {
2013
 
2014
  global $wpdb;
2016
  $where = '';
2017
 
2018
  if ( ! empty( $_POST['start_date'] ) ) {
2019
+
2020
  $date = new DateTime( sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
2021
  $date_formatted = $date->format( 'Y-m-d H:i:s' );
2022
+
2023
  $where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
2024
+
2025
  }
2026
  if ( ! empty( $_POST['end_date'] ) ) {
2027
+
2028
  $date = new DateTime( sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
2029
  $date_formatted = $date->format( 'Y-m-d H:i:s' );
2030
+
2031
  $where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
2032
+
2033
  }
2034
+
2035
+ // search by last update time of BP extended fields ##
2036
+ if (
2037
+ ( isset ($_POST['updated_since_date'] ) && $_POST['updated_since_date'] != '' )
2038
+ && (isset ($_POST['bp_field_updated_since'] ) && $_POST['bp_field_updated_since'] != '' )
2039
+ ) {
2040
+
2041
+ $last_updated_date = new DateTime( sanitize_text_field ( $_POST['updated_since_date'] ) . ' 00:00:00' );
2042
+ $this->updated_since_date = $last_updated_date->format( 'Y-m-d H:i:s' );
2043
+ $this->field_updated_since = sanitize_text_field ( $_POST['bp_field_updated_since'] );
2044
+ $field_updated_since_id = BP_Xprofile_Field::get_id_from_name( $this->field_updated_since );
2045
+ $user_search->query_from .= " JOIN `wp_bp_xprofile_data` XP ON XP.user_id = wp_users.ID ";
2046
+ $where .= $wpdb->prepare( " AND XP.field_id = %s AND XP.last_updated >= %s", $field_updated_since_id, $this->updated_since_date );
2047
+
2048
  }
2049
+
2050
  if ( ! empty( $where ) ) {
2051
+
2052
  $user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
2053
+
2054
  }
2055
 
2056
+ #wp_die( $this->pr( $user_search ) );
2057
  return $user_search;
2058
 
2059
  }
2061
 
2062
  /**
2063
  * Export Date Options
2064
+ *
2065
  * @since 0.9.6
2066
  * @global type $wpdb
2067
  * @return Array of objects
2068
  */
2069
+ protected function get_user_registered_dates()
2070
  {
2071
+
2072
  // invite in global objects ##
2073
  global $wpdb;
2074
+
2075
  // query user table for oldest and newest registration ##
2076
+ $range =
2077
+ $wpdb->get_results (
2078
+ #$wpdb->prepare (
2079
  "
2080
  SELECT
2081
  MIN( user_registered ) AS first,
2085
  "
2086
  #)
2087
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2088
 
2089
+ return $range;
 
2090
 
2091
  }
2092
 
2093
+
2094
  /**
2095
  * Quote array elements and separate with commas
2096
  *
2097
  * @since 0.9.6
2098
  * @return String
2099
  */
2100
+ protected function quote_array( $array )
2101
  {
2102
+
2103
  $prefix = ''; // starts empty ##
2104
  $elementlist = '';
2105
  if ( is_array( $array ) ) {
2108
  $prefix = ','; // prefix all remaining items with a comma ##
2109
  }
2110
  }
2111
+
2112
  // kick back string to function caller ##
2113
  return( $elementlist );
2114
+
2115
  }
2116
+
2117
+
2118
  /**
2119
+ * Recursively implodes an array
2120
+ *
2121
+ * @since 1.0.1
2122
+ * @access public
2123
+ * @param array $array multi-dimensional array to recursively implode
2124
+ * @param string $glue value that glues elements together
2125
+ * @param bool $include_keys include keys before their values
2126
+ * @param bool $trim_all trim ALL whitespace from string
2127
+ * @return string imploded array
2128
+ */
2129
+ protected function recursive_implode( $array, $return = null, $glue = '|' )
2130
  {
2131
+
2132
  // unserialize ##
2133
+ $array = $this->unserialize( $array );
2134
+
2135
  // kick it back ##
2136
+ if ( is_null ( $return ) && ! is_array( $array ) ) {
2137
+
2138
  return $array;
2139
+
2140
  }
2141
+
2142
  // empty return ##
2143
+ if ( is_null ( $return ) ) {
2144
+
2145
+ $return = '';
2146
+
2147
  } else {
2148
+
2149
  if ( "||" == $glue ) {
2150
+
2151
  $glue = '|||';
2152
+
2153
  } else if ( "|" == $glue ) {
2154
+
2155
  $glue = '||';
2156
+
2157
  }
2158
+
2159
  }
2160
+
2161
  // loop ##
2162
  foreach( $array as $key => $value ) {
2163
+
2164
  // unserialize ##
2165
+ $value = $this->unserialize( $value );
2166
+
2167
  if( is_array( $value ) ) {
2168
+
2169
+ $return .= $glue . $key . $glue . $this->recursive_implode( $value, $return, $glue );
2170
+
2171
  } else {
2172
+
2173
  $return .= $glue . $key . $glue . $value;
2174
+
2175
  }
2176
+
2177
  }
2178
 
2179
  // Removes first $glue from string ##
2180
+ if ( $glue && $return && $return[0] == '|' ) {
2181
 
2182
  $return = ltrim ( $return, '|' );
2183
+
2184
  }
2185
+
2186
  // Trim ALL whitespace ##
2187
  if ( $return ) {
2188
+
2189
  $return = preg_replace( "/(\s)/ixsm", '', $return );
2190
+
2191
  }
2192
+
2193
  // kick it back ##
2194
  return $return;
2195
+
2196
+ }
2197
+
2198
+
2199
  /**
2200
  * Save Unserializer
2201
+ *
2202
  * @since 1.1.4
2203
  */
2204
+ protected function unserialize( $value )
2205
  {
2206
+
2207
  // the $value is serialized ##
2208
  if ( is_serialized( $value ) ) {
2209
 
2225
  }
2226
 
2227
  }
2228
+
2229
  // kick it back ##
2230
  return $value;
2231
+
2232
  }
2233
+
2234
+
2235
  /**
2236
  * Encode special characters
2237
+ *
2238
  * @param type $string
2239
  * @return string Encoding string
2240
  * @since 1.2.3
2241
  */
2242
+ protected function special_characters( $string = null )
2243
  {
2244
+
2245
  // sanity check ##
2246
  if ( is_null( $string ) ) {
2247
+
2248
  return false;
2249
+
2250
  }
2251
+
2252
  // kick it back in a nicer format ##
2253
  return htmlentities( $string, ENT_COMPAT, 'UTF-8' );
2254
+
2255
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2256
 
2257
 
2258
  }
2259
 
2260
+ // hook plugin to workdpress action - defined in class ##
2261
+ add_action( Q_EUD_HOOK, 'q_export_user_data', Q_EUD_PRIORITY );
2262
+ /**
2263
+ * Instatiate class and load up schortcode
2264
+ *
2265
+ * @since 1.2.8
2266
+ * @return void
2267
+ */
2268
+ function q_export_user_data()
2269
+ {
2270
+
2271
+ // admin only ##
2272
+ if ( ! is_admin() ) { return false; }
2273
+
2274
+ // instatiate class ##
2275
+ $export_user_data = new Q_Export_User_Data();
2276
+
2277
+ // hook into wp fitlers and actions ##
2278
+ $export_user_data->run_hooks();
2279
+
2280
+ }
2281
+
2282
+
2283
  }
readme.md CHANGED
@@ -1,16 +1,16 @@
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.4.1
6
- **Stable tag:** 1.2.7
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
 
@@ -59,6 +59,17 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
59
 
60
  ## Changelog ##
61
 
 
 
 
 
 
 
 
 
 
 
 
62
  *** 1.2.7 ***
63
  * Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
64
 
@@ -83,10 +94,10 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
83
  ### 1.2.0 ###
84
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
85
 
86
- ### 1.1.1 ###
87
  * Removed accidently included .git files
88
 
89
- ### 1.1.0 ###
90
  * Version change to sync SVN on wordpress.org
91
 
92
  ### 1.0.4 ###
@@ -114,7 +125,7 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
114
  * added option to export all user WP Roles
115
 
116
  ### 0.9.8 ###
117
- * added get_usermeta() to check if meta keys are unique and return an array if not
118
  * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
119
 
120
  ### 0.9.7 ###
@@ -170,7 +181,7 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
170
  * fixes to allow exports without selecting extra user date from usermeta or x-profile
171
 
172
  ### 0.6.3 ###
173
- * added multiselect to pick usermeta and xprofile fields
174
 
175
  ### 0.5 ###
176
  * First public 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.4.2
6
+ **Stable tag:** 1.3.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
 
59
 
60
  ## Changelog ##
61
 
62
+ *** 1.3.0 ***
63
+ * Added extra data sanitization before outputting to file - thanks to Hely Shah <helyhshah@gmail.com> for te heads-up
64
+
65
+ *** 1.2.8 ***
66
+ * New: Added load_buddypress() methods to test for buddypress and load up if missing
67
+ * New: move action hooks and priority to load later
68
+ * New: Plugin no longer uses singleton model to instatiate - instead called from action hook to public function
69
+ * New: added log() to debug.log file to help debugging issues
70
+ * Update: jQuery datepickers pull start_of_week value from WordPress
71
+ * Tested on 4.4.2
72
+
73
  *** 1.2.7 ***
74
  * Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
75
 
94
  ### 1.2.0 ###
95
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
96
 
97
+ ### 1.1.1 ###
98
  * Removed accidently included .git files
99
 
100
+ ### 1.1.0 ###
101
  * Version change to sync SVN on wordpress.org
102
 
103
  ### 1.0.4 ###
125
  * added option to export all user WP Roles
126
 
127
  ### 0.9.8 ###
128
+ * added get_usermeta() to check if meta keys are unique and return an array if not
129
  * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
130
 
131
  ### 0.9.7 ###
181
  * fixes to allow exports without selecting extra user date from usermeta or x-profile
182
 
183
  ### 0.6.3 ###
184
+ * added multiselect to pick usermeta and xprofile fields
185
 
186
  ### 0.5 ###
187
  * First public release.
readme.txt CHANGED
@@ -2,15 +2,15 @@
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.4.1
6
- Stable tag: 1.2.7
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
 
@@ -58,6 +58,17 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
58
 
59
  == Changelog ==
60
 
 
 
 
 
 
 
 
 
 
 
 
61
  = 1.2.7 =
62
  * Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
63
 
@@ -75,21 +86,21 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
75
  = 1.2.2 =
76
  * Minor Fixes
77
 
78
- = 1.2.1 =
79
  * Checked on WP 4.3.1
80
  * Moved text-domain to string in preperation for addition to translate.wordpress.org
81
  * Added Log() method to allow for debugging to WP Error Log
82
  * Added Greek translation - Thanks @Leonidas Mi
83
  * Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
84
 
85
- = 1.2.0 =
86
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safer delimiters ( ||, ||| - etc. )
87
  * Removed anonymous function calls giving errors on older versions of PHP
88
 
89
- = 1.1.1 =
90
  * Removed accidently included .git files
91
 
92
- = 1.1.0 =
93
  * Version change to sync SVN on wordpress.org
94
 
95
  = 1.1.1 =
@@ -121,7 +132,7 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
121
  * added option to export all user WP Roles
122
 
123
  = 0.9.8 =
124
- * added get_usermeta() to check if meta keys are unique and return an array if not
125
  * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
126
 
127
  = 0.9.7 =
@@ -149,7 +160,7 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
149
  * Tested with WP 3.9
150
  * Fix for BuddyPress 2.0 bug
151
 
152
- = 0.9.0 =
153
  * Moved plugin class to singleton model
154
  * Improved language handling
155
  * French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
@@ -177,7 +188,7 @@ Click on the 'Export User Data' link in the 'Users' menu, choose the role and th
177
  * fixes to allow exports without selecting extra user date from usermeta or x-profile
178
 
179
  = 0.6.3 =
180
- * added multiselect to pick usermeta and xprofile fields
181
 
182
  = 0.5 =
183
  * First public release.
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.4.2
6
+ Stable tag: 1.3.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
 
58
 
59
  == Changelog ==
60
 
61
+ = 1.3.0 =
62
+ * Added extra data sanitization before outputting to file - thanks to Hely Shah <helyhshah@gmail.com> for te heads-up
63
+
64
+ = 1.2.8 =
65
+ * New: Added load_buddypress() methods to test for buddypress and load up if missing
66
+ * New: move action hooks and priority to load later
67
+ * New: Plugin no longer uses singleton model to instatiate - instead called from action hook to public function
68
+ * New: added log() to debug.log file to help debugging issues
69
+ * Update: jQuery datepickers pull start_of_week value from WordPress
70
+ * Tested on 4.4.2
71
+
72
  = 1.2.7 =
73
  * Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
74
 
86
  = 1.2.2 =
87
  * Minor Fixes
88
 
89
+ = 1.2.1 =
90
  * Checked on WP 4.3.1
91
  * Moved text-domain to string in preperation for addition to translate.wordpress.org
92
  * Added Log() method to allow for debugging to WP Error Log
93
  * Added Greek translation - Thanks @Leonidas Mi
94
  * Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
95
 
96
+ = 1.2.0 =
97
  * Data stored in recursive and serialized arrays is now exported in a flat string format with safer delimiters ( ||, ||| - etc. )
98
  * Removed anonymous function calls giving errors on older versions of PHP
99
 
100
+ = 1.1.1 =
101
  * Removed accidently included .git files
102
 
103
+ = 1.1.0 =
104
  * Version change to sync SVN on wordpress.org
105
 
106
  = 1.1.1 =
132
  * added option to export all user WP Roles
133
 
134
  = 0.9.8 =
135
+ * added get_usermeta() to check if meta keys are unique and return an array if not
136
  * removed known_arrays() filter to allow for array data to be returned correctly - too hacky
137
 
138
  = 0.9.7 =
160
  * Tested with WP 3.9
161
  * Fix for BuddyPress 2.0 bug
162
 
163
+ = 0.9.0 =
164
  * Moved plugin class to singleton model
165
  * Improved language handling
166
  * French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
188
  * fixes to allow exports without selecting extra user date from usermeta or x-profile
189
 
190
  = 0.6.3 =
191
+ * added multiselect to pick usermeta and xprofile fields
192
 
193
  = 0.5 =
194
  * First public release.