Version Description
Download this release
Release Info
Developer | qlstudio |
Plugin | Export User Data |
Version | 2.0.1 |
Comparing to | |
See all releases |
Code changes from version 1.3.1 to 2.0.1
- CHANGELOG.md +153 -0
- export-user-data.php +139 -2217
- library/admin/admin.php +838 -0
- library/admin/css/image/switch.png +0 -0
- library/admin/css/q-report.css +134 -0
- library/admin/javascript/jquery.multi-select.js +470 -0
- library/api/admin.php +231 -0
- library/core/buddypress.php +99 -0
- library/core/config.php +88 -0
- library/core/core.php +420 -0
- library/core/export.php +607 -0
- library/core/filters.php +59 -0
- library/core/helper.php +49 -0
- library/core/user.php +239 -0
- library/core/xml.php +112 -0
- library/languages/default.mo +0 -0
- library/languages/default.po +158 -0
- library/languages/export-user-data-el.mo +0 -0
- library/languages/export-user-data-el.po +167 -0
- library/languages/export-user-data-es_ES.mo +0 -0
- library/languages/export-user-data-es_ES.po +166 -0
- library/languages/export-user-data-fr_FR.mo +0 -0
- library/languages/export-user-data-fr_FR.po +166 -0
- readme.md +23 -198
- readme.txt +4 -200
CHANGELOG.md
ADDED
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Changelog ##
|
2 |
+
|
3 |
+
*** 2.0.1 ***
|
4 |
+
|
5 |
+
* Deprecated BuddyPress support as untested in 4 years
|
6 |
+
|
7 |
+
*** 2.0.0 ***
|
8 |
+
|
9 |
+
* Fork to new name Q Report
|
10 |
+
* namespaced and moved to standard Q plugin setup model
|
11 |
+
* buddypress support might be flaky due to limited testing
|
12 |
+
|
13 |
+
*** 1.3.1 ***
|
14 |
+
|
15 |
+
* Moved all internal action hooks to admin_init to allow for internal function loading
|
16 |
+
|
17 |
+
*** 1.3.0 ***
|
18 |
+
|
19 |
+
* Added extra data sanitization before outputting to file - thanks to Hely Shah <helyhshah@gmail.com> for te heads-up
|
20 |
+
|
21 |
+
*** 1.2.8 ***
|
22 |
+
|
23 |
+
* New: Added load_buddypress() methods to test for buddypress and load up if missing
|
24 |
+
* New: move action hooks and priority to load later
|
25 |
+
* New: Plugin no longer uses singleton model to instatiate - instead called from action hook to public function
|
26 |
+
* New: added log() to debug.log file to help debugging issues
|
27 |
+
* Update: jQuery datepickers pull start_of_week value from WordPress
|
28 |
+
* Tested on 4.4.2
|
29 |
+
|
30 |
+
*** 1.2.7 ***
|
31 |
+
|
32 |
+
* Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
|
33 |
+
|
34 |
+
*** 1.2.6 ***
|
35 |
+
* Update: WP 4.4.1
|
36 |
+
|
37 |
+
### 1.2.3 ###
|
38 |
+
* Fix: to remove minor security loop hole
|
39 |
+
* New: Added option to remove standard wp_users data from export
|
40 |
+
* Fix: removed roles and groups columns from export when options hidden
|
41 |
+
|
42 |
+
### 1.2.2 ###
|
43 |
+
* Minor FIxes
|
44 |
+
|
45 |
+
### 1.2.1 ###
|
46 |
+
* Checked on WP 4.3.1
|
47 |
+
* Moved text-domain to string in preperation for addition to translate.wordpress.org
|
48 |
+
* Added Log() method to allow for debugging to WP Error Log
|
49 |
+
* Added Greek translation - Thanks @Leonidas Mi
|
50 |
+
* Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
|
51 |
+
|
52 |
+
### 1.2.0 ###
|
53 |
+
* Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
|
54 |
+
|
55 |
+
### 1.1.1 ###
|
56 |
+
* Removed accidently included .git files
|
57 |
+
|
58 |
+
### 1.1.0 ###
|
59 |
+
* Version change to sync SVN on wordpress.org
|
60 |
+
|
61 |
+
### 1.0.4 ###
|
62 |
+
* Added unserialize function with @ fallback
|
63 |
+
* Removed anonymous function to allow support for PHP < 5.2
|
64 |
+
|
65 |
+
### 1.0.3 ###
|
66 |
+
* Tested as working on WordPress 4.1.0.
|
67 |
+
|
68 |
+
### 1.0.2 ###
|
69 |
+
* Removed get_user_meta method, as not effective.
|
70 |
+
* Added registration date from and to pickers - to replace monthly <select> lists.
|
71 |
+
|
72 |
+
### 1.0.1 ###
|
73 |
+
* Added recursive_implode() method to flatten data stored in arrays ( exported with keys and values divided by "|" )
|
74 |
+
|
75 |
+
### 1.0.0 ###
|
76 |
+
* Reduced all get_user_meta queries to a single call to improve performance
|
77 |
+
* Serialized data is now returned in it's pure stored format - not imploded or unserialized to avoid data structure loss
|
78 |
+
|
79 |
+
### 0.9.9 ###
|
80 |
+
* get_uermeta renamed get_user_meta to be more consistent with WP
|
81 |
+
* get_user_meta tidied up and tested on larger exports
|
82 |
+
* added option to export user BP Groups
|
83 |
+
* added option to export all user WP Roles
|
84 |
+
|
85 |
+
### 0.9.8 ###
|
86 |
+
* added get_usermeta() to check if meta keys are unique and return an array if not
|
87 |
+
* removed known_arrays() filter to allow for array data to be returned correctly - too hacky
|
88 |
+
|
89 |
+
### 0.9.7 ###
|
90 |
+
* Added known_arrays() filter to allow for array data to be returned correctly
|
91 |
+
|
92 |
+
### 0.9.6 ###
|
93 |
+
* Save, load and delete stored export settings - thanks to @cwjordan
|
94 |
+
* Overcome memory outages on large exports - thanks to @grexican
|
95 |
+
* Tested on WP 4.0.0 & BP 2.1.0
|
96 |
+
|
97 |
+
### 0.9.5 ###
|
98 |
+
* BP Serialized data fixes - thanks to @nicmare & @grexican
|
99 |
+
* Tested on WP 3.9.2 & BP 2.0.2
|
100 |
+
|
101 |
+
### 0.9.4 ###
|
102 |
+
* BP X Profile Export Fix ( > version 2.0 )
|
103 |
+
|
104 |
+
### 0.9.3 ###
|
105 |
+
* fix for hidden admin bar
|
106 |
+
|
107 |
+
### 0.9.2 ###
|
108 |
+
* removed $key assignment casting to integer
|
109 |
+
|
110 |
+
### 0.9.1 ###
|
111 |
+
* Tested with WP 3.9
|
112 |
+
* Fix for BuddyPress 2.0 bug
|
113 |
+
|
114 |
+
### 0.9.0 ###
|
115 |
+
* Moved plugin class to singleton model
|
116 |
+
* Improved language handling
|
117 |
+
* French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
|
118 |
+
|
119 |
+
### 0.8.3 ###
|
120 |
+
* clarified export limit options
|
121 |
+
|
122 |
+
### 0.8.2 ###
|
123 |
+
* corrected buddypress export option - broken in 0.8.1
|
124 |
+
* changed get_users arguments, in attempt to reduce memory usage
|
125 |
+
|
126 |
+
### 0.8.1 ###
|
127 |
+
* Added experimental range limiter for exports
|
128 |
+
* Extra input data sanitizing
|
129 |
+
|
130 |
+
### 0.8 ###
|
131 |
+
* moved plugin instatiation to the WP hook: init
|
132 |
+
* moved bp calls outside export loop
|
133 |
+
* added extra isset calls on values in export loop to clean up error log not sets
|
134 |
+
|
135 |
+
### 0.7.8 ###
|
136 |
+
* added xml template for Excel exports - thanks to phil@fixitlab.com :)
|
137 |
+
|
138 |
+
### 0.7.2 ###
|
139 |
+
* fixes to allow exports without selecting extra user date from usermeta or x-profile
|
140 |
+
|
141 |
+
### 0.6.3 ###
|
142 |
+
* added multiselect to pick usermeta and xprofile fields
|
143 |
+
|
144 |
+
### 0.5 ###
|
145 |
+
* First public release.
|
146 |
+
|
147 |
+
## Upgrade Notice ##
|
148 |
+
|
149 |
+
### 0.6.3 ###
|
150 |
+
Latest.
|
151 |
+
|
152 |
+
### 0.5 ###
|
153 |
+
First release.
|
export-user-data.php
CHANGED
@@ -1,2284 +1,206 @@
|
|
1 |
<?php
|
2 |
|
3 |
/*
|
4 |
-
Plugin Name:
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
Author:
|
9 |
-
|
10 |
-
|
11 |
-
Text Domain:
|
|
|
12 |
*/
|
13 |
|
14 |
-
|
15 |
-
|
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_HOOK_ADMIN', 'admin_init' ); // wp action to hook to ##
|
24 |
-
define( 'Q_EUD_PRIORITY', '1000000' ); // priority ##
|
25 |
-
define( 'Q_LOG_PREFIX', 'EUD' ); // wp action to hook to ##
|
26 |
-
|
27 |
-
// plugin version
|
28 |
-
define( 'Q_EUD', '1.3.0' ); // version ##
|
29 |
-
|
30 |
-
// on activate ##
|
31 |
-
#register_activation_hook( __FILE__, 'function' );
|
32 |
-
|
33 |
-
// on deactivate ##
|
34 |
-
#register_deactivation_hook( __FILE__, 'function' );
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Main plugin class
|
38 |
-
*
|
39 |
-
* @since 0.1
|
40 |
-
**/
|
41 |
-
class Q_Export_User_Data {
|
42 |
|
|
|
|
|
|
|
|
|
43 |
|
44 |
-
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
/* properties */
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
protected $bp_data_available = false;
|
65 |
-
protected $allowed_tags = '';
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Class contructor
|
71 |
-
*
|
72 |
-
* @since 0.1
|
73 |
-
**/
|
74 |
-
public function __construct()
|
75 |
-
{
|
76 |
-
|
77 |
-
// silence is golden ##
|
78 |
-
|
79 |
-
}
|
80 |
-
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Load plugin text-domain
|
84 |
-
*
|
85 |
-
* @since 0.9.0
|
86 |
-
* @return void
|
87 |
-
**/
|
88 |
-
public function load_plugin_textdomain()
|
89 |
-
{
|
90 |
-
|
91 |
-
// The "plugin_locale" filter is also used in load_plugin_textdomain()
|
92 |
-
$locale = apply_filters( 'plugin_locale', get_locale(), 'export-user-data' );
|
93 |
-
|
94 |
-
// try from global WP location first ##
|
95 |
-
load_textdomain( 'export-user-data', WP_LANG_DIR.'/plugins/export-user-data-'.$locale.'.mo' );
|
96 |
-
|
97 |
-
// try from plugin last ##
|
98 |
-
load_plugin_textdomain( 'export-user-data', false, basename( dirname( __FILE__ ) ) . '/languages' );
|
99 |
-
|
100 |
-
}
|
101 |
-
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Hook intro WP filters and actions
|
105 |
-
*
|
106 |
-
* @since 1.2.8
|
107 |
-
* @return void
|
108 |
-
*/
|
109 |
-
public function run_hooks()
|
110 |
-
{
|
111 |
-
|
112 |
-
// set text domain ##
|
113 |
-
add_action( 'init', array( $this, 'load_plugin_textdomain' ), 1 );
|
114 |
-
|
115 |
-
if ( is_admin() ) {
|
116 |
-
|
117 |
-
// load BP ##
|
118 |
-
add_action( Q_EUD_HOOK_ADMIN, array( $this, 'load_buddypress' ), Q_EUD_PRIORITY+1 );
|
119 |
-
|
120 |
-
// load user options ##
|
121 |
-
add_action( Q_EUD_HOOK_ADMIN, array( $this, 'load_user_options' ), Q_EUD_PRIORITY+2 );
|
122 |
-
|
123 |
-
// run export ##
|
124 |
-
add_action( Q_EUD_HOOK_ADMIN, array( $this, 'generate_data' ), Q_EUD_PRIORITY+3 );
|
125 |
-
|
126 |
-
// filter exported data - perhaps unused ##
|
127 |
-
#add_filter( 'q_eud_exclude_data', array( $this, 'exclude_data' ) );
|
128 |
-
|
129 |
-
// add export page inside admin ##
|
130 |
-
add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
|
131 |
-
|
132 |
-
// UI style and functionality ##
|
133 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 1 );
|
134 |
-
add_action( 'admin_footer', array( $this, 'jquery' ), 100000 );
|
135 |
-
add_action( 'admin_footer', array( $this, 'css' ), 100000 );
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
}
|
140 |
-
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Write to WP Error Log
|
144 |
-
*
|
145 |
-
* @since 1.5.0
|
146 |
-
* @return void
|
147 |
-
*/
|
148 |
-
protected function log( $log )
|
149 |
-
{
|
150 |
-
|
151 |
-
if ( $this->debug && true === WP_DEBUG ) {
|
152 |
-
|
153 |
-
$trace = debug_backtrace();
|
154 |
-
$caller = $trace[1];
|
155 |
-
|
156 |
-
$suffix = sprintf(
|
157 |
-
__( ' - %s%s() %s:%d', 'Q_Scrape_Wordpress' )
|
158 |
-
, isset($caller['class']) ? $caller['class'].'::' : ''
|
159 |
-
, $caller['function']
|
160 |
-
, isset( $caller['file'] ) ? $caller['file'] : 'n'
|
161 |
-
, isset( $caller['line'] ) ? $caller['line'] : 'x'
|
162 |
-
);
|
163 |
-
|
164 |
-
$prefix = Q_LOG_PREFIX.' ';
|
165 |
-
|
166 |
-
if ( is_array( $log ) || is_object( $log ) ) {
|
167 |
-
error_log( $prefix.print_r( $log, true ).$suffix );
|
168 |
-
} else {
|
169 |
-
error_log( $prefix.$log.$suffix );
|
170 |
-
}
|
171 |
-
|
172 |
-
}
|
173 |
-
|
174 |
-
}
|
175 |
-
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Nicer var_dump
|
179 |
-
*
|
180 |
-
* @since 0.9.6
|
181 |
-
*/
|
182 |
-
protected function pr ( $variable )
|
183 |
-
{
|
184 |
-
|
185 |
-
echo '<pre>';
|
186 |
-
print_r ( $variable );
|
187 |
-
echo '</pre>';
|
188 |
-
|
189 |
-
}
|
190 |
|
|
|
|
|
191 |
|
192 |
/**
|
193 |
-
*
|
194 |
*
|
195 |
-
* @
|
196 |
-
**/
|
197 |
-
public function add_admin_pages()
|
198 |
-
{
|
199 |
-
|
200 |
-
add_users_page( __( 'Export User Data', 'export-user-data' ), __( 'Export User Data', 'export-user-data' ), 'list_users', 'export-user-data', array( $this, 'users_page' ) );
|
201 |
-
|
202 |
-
}
|
203 |
-
|
204 |
-
|
205 |
-
/**
|
206 |
-
* style and interaction
|
207 |
*/
|
208 |
-
public function
|
209 |
{
|
210 |
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
wp_register_style( 'css-q_export_user_data', plugins_url( 'css/export-user-data.css' ,__FILE__ ), '', Q_EUD );
|
215 |
-
wp_enqueue_style( 'css-q_export_user_data' );
|
216 |
-
wp_enqueue_script( 'q_eud_multi_select_js', plugins_url( 'js/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
|
217 |
-
|
218 |
-
// add script ##
|
219 |
-
wp_enqueue_script('jquery-ui-datepicker');
|
220 |
-
|
221 |
-
// add style ##
|
222 |
-
wp_enqueue_style( 'jquery-ui-datepicker' );
|
223 |
-
wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
|
224 |
-
|
225 |
}
|
226 |
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Return Byte count of $val
|
232 |
-
*
|
233 |
-
* @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
|
234 |
-
* @since 0.9.6
|
235 |
-
*/
|
236 |
-
protected function return_bytes( $val )
|
237 |
-
{
|
238 |
-
|
239 |
-
$val = trim( $val );
|
240 |
-
$last = strtolower($val[strlen($val)-1]);
|
241 |
-
switch( $last ) {
|
242 |
|
243 |
-
// The 'G' modifier is available since PHP 5.1.0
|
244 |
-
case 'g':
|
245 |
-
|
246 |
-
$val *= 1024;
|
247 |
-
|
248 |
-
case 'm':
|
249 |
-
|
250 |
-
$val *= 1024;
|
251 |
-
|
252 |
-
case 'k':
|
253 |
-
|
254 |
-
$val *= 1024;
|
255 |
-
|
256 |
-
}
|
257 |
-
|
258 |
-
return $val;
|
259 |
}
|
260 |
-
|
261 |
-
|
262 |
/**
|
263 |
-
*
|
264 |
-
*
|
265 |
-
* @since
|
266 |
-
* @return
|
267 |
*/
|
268 |
-
|
269 |
{
|
|
|
|
|
|
|
270 |
|
271 |
-
//
|
272 |
-
|
273 |
-
$value = str_replace("\n", '', $value);
|
274 |
-
$value = str_replace("\t", '', $value);
|
275 |
|
276 |
-
//
|
277 |
-
|
278 |
-
|
279 |
-
//
|
280 |
-
|
281 |
-
|
282 |
-
// return value ##
|
283 |
-
return $value;
|
284 |
|
285 |
}
|
286 |
|
287 |
|
288 |
-
|
289 |
-
|
290 |
-
*
|
291 |
-
* @since 1.2.8
|
292 |
-
* @return Array
|
293 |
-
*/
|
294 |
-
protected function get_allowed_tags()
|
295 |
-
{
|
296 |
|
297 |
-
|
298 |
-
'a' => array(
|
299 |
-
'href' => array(),
|
300 |
-
'title' => array()
|
301 |
-
),
|
302 |
-
'br' => array(),
|
303 |
-
'em' => array(),
|
304 |
-
'strong' => array(),
|
305 |
-
);
|
306 |
|
307 |
-
|
|
|
|
|
308 |
|
309 |
}
|
310 |
|
311 |
|
|
|
312 |
|
313 |
-
|
314 |
-
* Load up saved exports for this user
|
315 |
-
* Set to public as hooked into action
|
316 |
-
*
|
317 |
-
* @since 0.9.6
|
318 |
-
* @return Array of saved exports
|
319 |
-
*/
|
320 |
-
public function load_buddypress()
|
321 |
-
{
|
322 |
-
|
323 |
-
// do we have a bp object in the globals ##
|
324 |
-
if (
|
325 |
-
is_plugin_active( 'buddypress/bp-loader.php' ) // plugin active
|
326 |
-
&& function_exists ( 'buddypress' ) // loader function exists ##
|
327 |
-
&& ! isset( $GLOBALS['bp'] ) // but global unavailble ##
|
328 |
-
) {
|
329 |
-
|
330 |
-
$this->log( 'BP not loaded - calling buddpress()' );
|
331 |
-
|
332 |
-
// call BP
|
333 |
-
buddypress();
|
334 |
-
|
335 |
-
return true;
|
336 |
-
|
337 |
-
}
|
338 |
-
|
339 |
-
#$this->log( 'BP loaded' );
|
340 |
-
|
341 |
-
return true;
|
342 |
|
343 |
}
|
344 |
|
345 |
|
|
|
346 |
/**
|
347 |
-
* Load
|
348 |
-
*
|
349 |
-
*
|
350 |
-
*
|
351 |
-
* @return Array of saved exports
|
352 |
*/
|
353 |
-
public function
|
354 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
|
356 |
-
|
357 |
-
$
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
}
|
364 |
-
|
365 |
-
|
|
|
366 |
/**
|
367 |
-
* Get
|
368 |
-
*
|
369 |
-
* @since 0.
|
370 |
-
* @
|
|
|
371 |
*/
|
372 |
-
|
373 |
{
|
374 |
|
375 |
-
|
376 |
-
$q_eud_exports = array_filter( $this->q_eud_exports );
|
377 |
-
|
378 |
-
// quick check if the array is empty ##
|
379 |
-
if ( empty ( $q_eud_exports ) ) {
|
380 |
-
|
381 |
-
return false;
|
382 |
-
|
383 |
-
}
|
384 |
-
|
385 |
-
// test the array of saved exports ##
|
386 |
-
#$this->pr( $q_eud_exports );
|
387 |
-
|
388 |
-
// start with an empty array ##
|
389 |
-
$exports = array();
|
390 |
-
|
391 |
-
// loop over each saved export and grab each key ##
|
392 |
-
foreach ( $q_eud_exports as $key => $value ) {
|
393 |
-
|
394 |
-
$exports[] = $key;
|
395 |
-
|
396 |
-
}
|
397 |
-
|
398 |
-
// kick back array ##
|
399 |
-
return( $exports );
|
400 |
|
401 |
}
|
402 |
-
|
403 |
-
|
404 |
/**
|
405 |
-
*
|
406 |
-
*
|
407 |
-
* @since 0.
|
408 |
-
* @
|
|
|
409 |
*/
|
410 |
-
|
411 |
{
|
412 |
|
413 |
-
|
414 |
-
if ( is_null ( $export ) ) { return false; }
|
415 |
-
|
416 |
-
if ( isset( $this->q_eud_exports[$export] ) ) {
|
417 |
-
|
418 |
-
$this->usermeta_saved_fields = $this->q_eud_exports[$export]['usermeta_saved_fields'];
|
419 |
-
$this->bp_fields_saved_fields = $this->q_eud_exports[$export]['bp_fields_saved_fields'];
|
420 |
-
$this->bp_fields_update_time_saved_fields = $this->q_eud_exports[$export]['bp_fields_update_time_saved_fields'];
|
421 |
-
$this->updated_since_date = isset( $this->q_eud_exports[$export]['updated_since_date'] ) ? $this->q_eud_exports[$export]['updated_since_date'] : null ;
|
422 |
-
$this->field_updated_since = isset( $this->q_eud_exports[$export]['field_updated_since'] ) ? $this->q_eud_exports[$export]['field_updated_since'] : null ;
|
423 |
-
$this->role = $this->q_eud_exports[$export]['role'];
|
424 |
-
$this->roles = $this->q_eud_exports[$export]['roles'];
|
425 |
-
$this->groups = $this->q_eud_exports[$export]['groups'];
|
426 |
-
$this->user_fields = isset( $this->q_eud_exports[$export]['user_fields'] ) ? $this->q_eud_exports[$export]['user_fields'] : null ;
|
427 |
-
$this->start_date = $this->q_eud_exports[$export]['start_date'];
|
428 |
-
$this->end_date = $this->q_eud_exports[$export]['end_date'];
|
429 |
-
$this->limit_offset = $this->q_eud_exports[$export]['limit_offset'];
|
430 |
-
$this->limit_total = $this->q_eud_exports[$export]['limit_total'];
|
431 |
-
$this->format = $this->q_eud_exports[$export]['format'];
|
432 |
-
|
433 |
-
} else {
|
434 |
-
|
435 |
-
$this->usermeta_saved_fields = array();
|
436 |
-
$this->bp_fields_saved_fields = array();
|
437 |
-
$this->bp_fields_update_time_saved_fields = array();
|
438 |
-
$this->updated_since_date = '';
|
439 |
-
$this->field_updated_since = '';
|
440 |
-
$this->role = '';
|
441 |
-
$this->user_fields = '1';
|
442 |
-
$this->roles = '1';
|
443 |
-
$this->groups = '1';
|
444 |
-
$this->start_date = '';
|
445 |
-
$this->end_date = '';
|
446 |
-
$this->limit_offset = '';
|
447 |
-
$this->limit_total = '';
|
448 |
-
$this->format = '';
|
449 |
-
|
450 |
-
}
|
451 |
|
452 |
}
|
453 |
-
|
454 |
-
|
455 |
-
/**
|
456 |
-
* Method to store user options
|
457 |
-
*
|
458 |
-
* @param string $save_export Export Key name
|
459 |
-
* @param array $save_options Array of export options to save
|
460 |
-
* @since 0.9.3
|
461 |
-
* @return void
|
462 |
-
*/
|
463 |
-
protected function set_user_options( $key = null, $options = null )
|
464 |
-
{
|
465 |
-
|
466 |
-
// sanity check ##
|
467 |
-
if ( is_null ( $key ) || is_null ( $options ) ) {
|
468 |
-
|
469 |
-
#$this->pr( 'missing save values' );
|
470 |
-
return false;
|
471 |
-
|
472 |
-
}
|
473 |
-
|
474 |
-
#$this->pr( $key );
|
475 |
-
#$this->pr( $options );
|
476 |
-
|
477 |
-
// for now, I'm simply allowing keys to be resaved - but this is not so logical ##
|
478 |
-
if ( array_key_exists( $key, $this->q_eud_exports ) ) {
|
479 |
-
|
480 |
-
#$this->pr( 'key exists, skipping save' );
|
481 |
-
#return false;
|
482 |
-
|
483 |
-
}
|
484 |
-
|
485 |
-
if ( isset( $options ) && is_array( $options ) ) {
|
486 |
-
|
487 |
-
// update_option sanitizes the option name but not the option value ##
|
488 |
-
foreach ( $options as $field_name => $field_value ) {
|
489 |
-
|
490 |
-
// so do that here. ##
|
491 |
-
if ( is_array( $field_value ) ) {
|
492 |
-
|
493 |
-
foreach ( $field_value as $field_array_key => $field_array_value ) {
|
494 |
-
|
495 |
-
$options[$field_name][$field_array_key] = sanitize_text_field( $field_array_value );
|
496 |
-
|
497 |
-
}
|
498 |
-
|
499 |
-
} else {
|
500 |
-
|
501 |
-
$options[$field_name] = sanitize_text_field( $field_value );
|
502 |
-
|
503 |
-
}
|
504 |
-
|
505 |
-
}
|
506 |
-
|
507 |
-
// assign the sanitized array of values to the class property $q_eud_exports as a new array with key $key ##
|
508 |
-
$this->q_eud_exports[$key] = $options;
|
509 |
-
|
510 |
-
// update stored user_meta values, if previous key found ##
|
511 |
-
if ( get_user_meta( get_current_user_id(), 'q_eud_exports' ) !== false ) {
|
512 |
-
|
513 |
-
#update_option( 'q_eud_exports', $this->q_eud_exports );
|
514 |
-
update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
|
515 |
-
|
516 |
-
// create new user meta key ##
|
517 |
-
} else {
|
518 |
-
|
519 |
-
#add_option( 'q_eud_exports', $this->q_eud_exports, $deprecated, $autoload );
|
520 |
-
add_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
|
521 |
-
|
522 |
-
}
|
523 |
-
|
524 |
-
}
|
525 |
-
|
526 |
-
}
|
527 |
-
|
528 |
|
529 |
/**
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
*/
|
536 |
-
protected function delete_user_options( $key = null )
|
537 |
{
|
538 |
|
539 |
-
//
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
// drop the array by it's key name from the class property ##
|
549 |
-
unset( $this->q_eud_exports[$key] );
|
550 |
-
|
551 |
-
// update the saved data ##
|
552 |
-
update_user_meta( get_current_user_id(), 'q_eud_exports', $this->q_eud_exports );
|
553 |
-
|
554 |
-
}
|
555 |
-
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Copy of BP_XProfile_ProfileData::get_all_for_user() from BP version 2.0?
|
559 |
-
* Get all of the profile information for a specific user.
|
560 |
-
*
|
561 |
-
* @param $user_id Integer ID of specific user
|
562 |
-
* @since 0.9.6
|
563 |
-
* @return Array User profile fields
|
564 |
-
* @deprecated since 1.2.1
|
565 |
-
*/
|
566 |
-
protected function get_all_for_user( $user_id = null )
|
567 |
-
{
|
568 |
-
|
569 |
-
// sanity check ##
|
570 |
-
if ( is_null( $user_id ) ) { return false; }
|
571 |
-
|
572 |
-
global $wpdb, $bp;
|
573 |
-
|
574 |
-
$bp = buddypress();
|
575 |
-
|
576 |
-
$results = $wpdb->get_results(
|
577 |
-
$wpdb->prepare(
|
578 |
-
"
|
579 |
-
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
|
580 |
-
FROM {$bp->profile->table_name_groups} g
|
581 |
-
LEFT JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id
|
582 |
-
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
|
583 |
-
WHERE d.user_id = %d AND d.value != ''
|
584 |
-
"
|
585 |
-
, $user_id
|
586 |
-
)
|
587 |
-
);
|
588 |
-
|
589 |
-
$profile_data = array();
|
590 |
-
|
591 |
-
if ( ! empty( $results ) ) {
|
592 |
|
593 |
-
|
594 |
-
|
595 |
-
$profile_data['user_email'] = $results[0]->user_email;
|
596 |
-
|
597 |
-
foreach( (array) $results as $field ) {
|
598 |
-
|
599 |
-
$profile_data[$field->field_name] = array(
|
600 |
-
'field_group_id' => $field->field_group_id,
|
601 |
-
'field_group_name' => $field->field_group_name,
|
602 |
-
'field_id' => $field->field_id,
|
603 |
-
'field_type' => $field->field_type,
|
604 |
-
'field_data' => $field->field_data
|
605 |
-
);
|
606 |
-
|
607 |
-
}
|
608 |
-
|
609 |
-
}
|
610 |
-
|
611 |
-
return $profile_data;
|
612 |
|
|
|
|
|
|
|
613 |
}
|
614 |
|
615 |
-
|
616 |
-
/**
|
617 |
-
* Attempt to generate the export file based on the passed arguements
|
618 |
-
*
|
619 |
-
* @since 0.1
|
620 |
-
* @return Mixes
|
621 |
-
**/
|
622 |
-
public function generate_data()
|
623 |
-
{
|
624 |
-
|
625 |
-
// Check if the user clicked on the Save, Load, or Delete Settings buttons ##
|
626 |
-
if (
|
627 |
-
! isset( $_POST['_wpnonce-q-eud-export-user-page_export'] )
|
628 |
-
|| isset( $_POST['load_export'] )
|
629 |
-
|| isset( $_POST['save_export'] )
|
630 |
-
|| isset( $_POST['delete_export'] ) )
|
631 |
-
{
|
632 |
-
|
633 |
-
return false;
|
634 |
-
|
635 |
-
}
|
636 |
-
|
637 |
-
// Increase maximum execution time to prevent "Maximum execution time exceeded" error ##
|
638 |
-
ini_set( 'max_execution_time', -1 );
|
639 |
-
ini_set( 'memory_limit', -1 ); // looks like a bad idea ##
|
640 |
-
|
641 |
-
// check admin referer ##
|
642 |
-
check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' );
|
643 |
-
|
644 |
-
// build argument array ##
|
645 |
-
$args = array(
|
646 |
-
'fields' => ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) ? 'all' : array( 'ID' ), // exclude standard wp_users fields from get_users query ##
|
647 |
-
'role' => sanitize_text_field( $_POST['role'] )
|
648 |
-
);
|
649 |
-
|
650 |
-
// did they request a specific program ? ##
|
651 |
-
if ( isset( $_POST['program'] ) && $_POST['program'] != '' ) {
|
652 |
-
|
653 |
-
$args['meta_key'] = 'member_of_club';
|
654 |
-
$args['meta_value'] = (int)$_POST['program'];
|
655 |
-
$args['meta_compare'] = '=';
|
656 |
-
|
657 |
-
}
|
658 |
-
|
659 |
-
// is there a range limit in place for the export ? ##
|
660 |
-
if ( isset( $_POST['limit_total'] ) && $_POST['limit_total'] != '' ) {
|
661 |
-
|
662 |
-
// let's just make sure they are integer values ##
|
663 |
-
$limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
|
664 |
-
$limit_total = (int)$_POST['limit_total'];
|
665 |
-
|
666 |
-
if ( is_int( $limit_offset ) && is_int( $limit_total ) ) {
|
667 |
-
|
668 |
-
$args['offset'] = $limit_offset;
|
669 |
-
$args['number'] = $limit_total; // number - Limit the total number of users returned ##
|
670 |
-
|
671 |
-
// test it ##
|
672 |
-
#wp_die( $this->pr( $args ) );
|
673 |
-
|
674 |
-
}
|
675 |
-
|
676 |
-
}
|
677 |
-
|
678 |
-
// pre_user query ##
|
679 |
-
add_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
|
680 |
-
$users = get_users( $args );
|
681 |
-
remove_action( 'pre_user_query', array( $this, 'pre_user_query' ) );
|
682 |
-
|
683 |
-
// test args ##
|
684 |
-
#wp_die( $this->pr ( $users ) );
|
685 |
-
|
686 |
-
// no users found, so chuck an error into the args array and exit the export ##
|
687 |
-
if ( ! $users ) {
|
688 |
-
|
689 |
-
wp_redirect( add_query_arg( 'error', 'empty', wp_get_referer() ) );
|
690 |
-
exit;
|
691 |
-
|
692 |
-
}
|
693 |
-
|
694 |
-
// get sitename and clean it up ##
|
695 |
-
$sitename = sanitize_key( get_bloginfo( 'name' ) );
|
696 |
-
if ( ! empty( $sitename ) ) {
|
697 |
-
$sitename .= '.';
|
698 |
-
}
|
699 |
-
|
700 |
-
// export method ? ##
|
701 |
-
$export_method = 'excel'; // default to Excel export ##
|
702 |
-
if ( isset( $_POST['format'] ) && $_POST['format'] != '' ) {
|
703 |
-
|
704 |
-
$export_method = sanitize_text_field( $_POST['format'] );
|
705 |
-
|
706 |
-
}
|
707 |
-
|
708 |
-
// set export filename structure ##
|
709 |
-
$filename = $sitename . 'users.' . date( 'Y-m-d-H-i-s' );
|
710 |
-
|
711 |
-
switch ( $export_method ) {
|
712 |
-
|
713 |
-
case ( 'csv' ):
|
714 |
-
|
715 |
-
// to csv ##
|
716 |
-
header( 'Content-Description: File Transfer' );
|
717 |
-
header( 'Content-Disposition: attachment; filename='.$filename.'.csv' );
|
718 |
-
header( 'Content-Type: text/csv; charset=' . get_option( 'blog_charset' ), true );
|
719 |
-
|
720 |
-
// set a csv check flag
|
721 |
-
$is_csv = true;
|
722 |
-
|
723 |
-
// nothing here
|
724 |
-
$doc_begin = '';
|
725 |
-
|
726 |
-
//preformat
|
727 |
-
$pre = '';
|
728 |
-
|
729 |
-
// how to seperate data ##
|
730 |
-
$seperator = ','; // comma for csv ##
|
731 |
-
|
732 |
-
// line break ##
|
733 |
-
$breaker = "\n";
|
734 |
-
|
735 |
-
// nothing here
|
736 |
-
$doc_end = '';
|
737 |
-
|
738 |
-
break;
|
739 |
-
|
740 |
-
case ( 'excel' ):
|
741 |
-
|
742 |
-
// to xls ##
|
743 |
-
header( 'Content-Description: File Transfer' );
|
744 |
-
header("Content-Type: application/vnd.ms-excel");
|
745 |
-
header("Content-Disposition: attachment; filename=$filename.xls");
|
746 |
-
header("Pragma: no-cache");
|
747 |
-
header("Expires: 0");
|
748 |
-
|
749 |
-
// set a csv check flag
|
750 |
-
$is_csv = false;
|
751 |
-
|
752 |
-
//grab the template file (for tidy formatting)
|
753 |
-
include( 'xml-template.php' );
|
754 |
-
|
755 |
-
// open xml
|
756 |
-
$doc_begin = $xml_doc_begin;
|
757 |
-
|
758 |
-
//preformat
|
759 |
-
$pre = $xml_pre;
|
760 |
-
|
761 |
-
// how to seperate data ##
|
762 |
-
$seperator = $xml_seperator;
|
763 |
-
|
764 |
-
// line break ##
|
765 |
-
$breaker = $xml_breaker;
|
766 |
-
|
767 |
-
// close xml
|
768 |
-
$doc_end = $xml_doc_end;
|
769 |
-
|
770 |
-
break;
|
771 |
-
|
772 |
-
}
|
773 |
-
|
774 |
-
|
775 |
-
// check for selected usermeta fields ##
|
776 |
-
$usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
|
777 |
-
#$this->pr( $usermeta );
|
778 |
-
$usermeta_fields = array();
|
779 |
-
|
780 |
-
if ( $usermeta && is_array( $usermeta ) ) {
|
781 |
-
foreach( $usermeta as $field ) {
|
782 |
-
$usermeta_fields[] = sanitize_text_field ( $field );
|
783 |
-
}
|
784 |
-
}
|
785 |
-
|
786 |
-
#$this->pr( $usermeta_fields );
|
787 |
-
#exit;
|
788 |
-
|
789 |
-
// check for selected x profile fields ##
|
790 |
-
$bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '';
|
791 |
-
$bp_fields_passed = array();
|
792 |
-
if ( $bp_fields && is_array( $bp_fields ) ) {
|
793 |
-
|
794 |
-
foreach( $bp_fields as $field ) {
|
795 |
-
|
796 |
-
// reverse tidy ##
|
797 |
-
$field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
|
798 |
-
|
799 |
-
// add to array ##
|
800 |
-
$bp_fields_passed[] = $field;
|
801 |
-
|
802 |
-
}
|
803 |
-
|
804 |
-
}
|
805 |
-
|
806 |
-
// cwjordan: check for x profile fields we want update time for ##
|
807 |
-
$bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '';
|
808 |
-
$bp_fields_update_passed = array();
|
809 |
-
if ( $bp_fields_update && is_array( $bp_fields_update ) ) {
|
810 |
-
|
811 |
-
foreach( $bp_fields_update as $field ) {
|
812 |
-
|
813 |
-
// reverse tidy ##
|
814 |
-
$field = str_replace( '__', ' ', sanitize_text_field ( $field ) );
|
815 |
-
|
816 |
-
// add to array ##
|
817 |
-
$bp_fields_update_passed[] = $field . " Update Date";
|
818 |
-
|
819 |
-
}
|
820 |
-
|
821 |
-
}
|
822 |
-
|
823 |
-
// global wpdb object ##
|
824 |
-
global $wpdb;
|
825 |
-
|
826 |
-
// debug ##
|
827 |
-
#$this->log( 'merging array' );
|
828 |
-
|
829 |
-
// compile final fields list ##
|
830 |
-
$fields = array_merge(
|
831 |
-
$this->get_user_fields() // standard wp_user fields ##
|
832 |
-
, $this->get_special_fields() // 'special' fields - which are controlled via dedicated checks ##
|
833 |
-
, $usermeta_fields // wp_user_meta fields ##
|
834 |
-
, $bp_fields_passed // selected buddypress fields ##
|
835 |
-
, $bp_fields_update_passed // update date for buddypress fields ##
|
836 |
-
);
|
837 |
-
|
838 |
-
// test field array ##
|
839 |
-
#$this->pr( $fields );
|
840 |
-
|
841 |
-
// build the document headers ##
|
842 |
-
$headers = array();
|
843 |
-
|
844 |
-
foreach ( $fields as $key => $field ) {
|
845 |
-
|
846 |
-
#$this->log( 'Field: '. $field );
|
847 |
-
|
848 |
-
// rename programs field ##
|
849 |
-
if ( $field == 'member_of_club' ){
|
850 |
-
$field = 'Program';
|
851 |
-
}
|
852 |
-
|
853 |
-
// grab fields to exclude from exports ##
|
854 |
-
if ( in_array( $fields[$key], $this->get_exclude_fields() ) ) {
|
855 |
-
|
856 |
-
#$this->log( 'Dump Field: '. $fields[$key] );
|
857 |
-
|
858 |
-
// ditch 'em ##
|
859 |
-
unset( $fields[$key] );
|
860 |
-
|
861 |
-
} else {
|
862 |
-
|
863 |
-
if ( $is_csv ) {
|
864 |
-
|
865 |
-
$headers[] = '"' . $field . '"';
|
866 |
-
|
867 |
-
} else {
|
868 |
-
|
869 |
-
$headers[] = $field;
|
870 |
-
#echo '<script>console.log("Echoing header cell: '.$field.'")</script>';
|
871 |
-
|
872 |
-
}
|
873 |
-
|
874 |
-
}
|
875 |
-
|
876 |
-
}
|
877 |
-
|
878 |
-
// quick check ##
|
879 |
-
#$this->log( $fields );
|
880 |
-
#if ( $this->debug ) $this->log( '$bp_fields_passed: '. var_dump( $bp_fields_passed ) );
|
881 |
-
|
882 |
-
// no more buffering while spitting back the export data ##
|
883 |
-
ob_end_flush();
|
884 |
-
|
885 |
-
// get the value in bytes allocated for Memory via php.ini ##
|
886 |
-
// @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
|
887 |
-
$memory_limit = $this->return_bytes( ini_get('memory_limit') ) * .75;
|
888 |
-
|
889 |
-
// we need to disable caching while exporting because we export so much data that it could blow the memory cache
|
890 |
-
// if we can't override the cache here, we'll have to clear it later...
|
891 |
-
if ( function_exists( 'override_function' ) ) {
|
892 |
-
|
893 |
-
override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
|
894 |
-
override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
|
895 |
-
override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
|
896 |
-
override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
|
897 |
-
|
898 |
-
} elseif ( function_exists( 'runkit_function_redefine' ) ) {
|
899 |
-
|
900 |
-
runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
|
901 |
-
runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
|
902 |
-
runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
|
903 |
-
runkit_function_redefine('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
|
904 |
-
|
905 |
-
}
|
906 |
-
|
907 |
-
// open doc wrapper.. ##
|
908 |
-
echo $doc_begin;
|
909 |
-
|
910 |
-
// echo headers ##
|
911 |
-
echo $pre . implode( $seperator, $headers ) . $breaker;
|
912 |
-
|
913 |
-
#wp_die( $this->pr( $users ) );
|
914 |
-
|
915 |
-
// build row values for each user ##
|
916 |
-
foreach ( $users as $user ) {
|
917 |
-
|
918 |
-
#wp_die( $this->pr( $user ) );
|
919 |
-
|
920 |
-
// check if we're hitting any Memory limits, if so flush them out ##
|
921 |
-
// per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
|
922 |
-
if ( memory_get_usage( true ) > $memory_limit ) {
|
923 |
-
wp_cache_flush();
|
924 |
-
}
|
925 |
-
|
926 |
-
// open up a new empty array ##
|
927 |
-
$data = array();
|
928 |
-
|
929 |
-
// BP loaded ? ##
|
930 |
-
if (
|
931 |
-
! $this->bp_data_available
|
932 |
-
&& function_exists ( 'bp_is_active' )
|
933 |
-
&& bp_is_active( 'xprofile' )
|
934 |
-
&& class_exists( 'BP_XProfile_ProfileData' )
|
935 |
-
&& method_exists( 'BP_XProfile_ProfileData', 'get_all_for_user' )
|
936 |
-
&& is_callable ( array( 'BP_XProfile_ProfileData', 'get_all_for_user' ) )
|
937 |
-
) {
|
938 |
-
|
939 |
-
$this->log( 'XProfile Accessible' );
|
940 |
-
$this->bp_data_available = true; // we only need to check for BP once ##
|
941 |
-
|
942 |
-
}
|
943 |
-
|
944 |
-
// grab all user data ##
|
945 |
-
if (
|
946 |
-
$this->bp_data_available
|
947 |
-
&& ! $bp_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID )
|
948 |
-
) {
|
949 |
-
|
950 |
-
// null the data to be sure ##
|
951 |
-
$bp_data = false;
|
952 |
-
|
953 |
-
$this->log( 'XProfile returned no data ID#: '.$user->ID );
|
954 |
-
|
955 |
-
}
|
956 |
-
|
957 |
-
// single query method - get all user_meta data ##
|
958 |
-
$get_user_meta = (array)get_user_meta( $user->ID );
|
959 |
-
#wp_die( $this->pr( $get_user_meta ) );
|
960 |
-
|
961 |
-
// Filter out empty meta data ##
|
962 |
-
#$get_user_meta = array_filter( array_map( function( $a ) {
|
963 |
-
# return $a[0];
|
964 |
-
#}, $get_user_meta ) );
|
965 |
-
|
966 |
-
// loop over each field ##
|
967 |
-
foreach ( $fields as $field ) {
|
968 |
-
|
969 |
-
// check if this is a BP field ##
|
970 |
-
if ( isset( $bp_data ) && isset( $bp_data[$field] ) && in_array( $field, $bp_fields_passed ) )
|
971 |
-
{
|
972 |
-
|
973 |
-
// old way from single BP query ##
|
974 |
-
$value = $bp_data[$field];
|
975 |
-
|
976 |
-
if ( is_array( $value ) ) {
|
977 |
-
|
978 |
-
$value = maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
|
979 |
-
#$value = $value['field_data'];
|
980 |
-
|
981 |
-
/**
|
982 |
-
* cwjordan
|
983 |
-
* after unserializing it we then
|
984 |
-
* need to implode it so
|
985 |
-
* that we have something readable?
|
986 |
-
* Going to use :: as a separator
|
987 |
-
* because that's what Buddypress Members Import
|
988 |
-
* expects, but we might want to make that
|
989 |
-
* configurable.
|
990 |
-
*/
|
991 |
-
if ( is_array( $value ) ) {
|
992 |
-
$value = implode("::", $value );
|
993 |
-
}
|
994 |
-
|
995 |
-
}
|
996 |
-
|
997 |
-
// sanitize ##
|
998 |
-
#$value = $this->sanitize($value);
|
999 |
-
|
1000 |
-
// check if this is a BP field we want the updated date for ##
|
1001 |
-
}
|
1002 |
-
elseif ( in_array( $field, $bp_fields_update_passed ) )
|
1003 |
-
{
|
1004 |
-
|
1005 |
-
global $bp;
|
1006 |
-
|
1007 |
-
$real_field = str_replace(" Update Date", "", $field);
|
1008 |
-
$field_id = xprofile_get_field_id_from_name( $real_field );
|
1009 |
-
$value = $wpdb->get_var (
|
1010 |
-
$wpdb->prepare(
|
1011 |
-
"
|
1012 |
-
SELECT last_updated
|
1013 |
-
FROM {$bp->profile->table_name_data}
|
1014 |
-
WHERE user_id = %d AND field_id = %d
|
1015 |
-
"
|
1016 |
-
, $user->ID
|
1017 |
-
, $field_id
|
1018 |
-
)
|
1019 |
-
);
|
1020 |
-
|
1021 |
-
// include the user's role in the export ##
|
1022 |
-
}
|
1023 |
-
elseif ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] && $field == 'roles' )
|
1024 |
-
{
|
1025 |
-
|
1026 |
-
// add "Role" as $value ##
|
1027 |
-
$value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
|
1028 |
-
|
1029 |
-
// include the user's BP group in the export ##
|
1030 |
-
}
|
1031 |
-
elseif ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] && $field == 'groups' )
|
1032 |
-
{
|
1033 |
-
|
1034 |
-
if ( function_exists( 'groups_get_user_groups' ) ) {
|
1035 |
-
|
1036 |
-
// check if user is a member of any groups ##
|
1037 |
-
$group_ids = groups_get_user_groups( $user->ID );
|
1038 |
-
|
1039 |
-
#$this->pr( $group_ids );
|
1040 |
-
#wp_die( pr( 'loaded group data.' ));
|
1041 |
-
|
1042 |
-
if ( ! $group_ids || $group_ids == '' ) {
|
1043 |
-
|
1044 |
-
$value = '';
|
1045 |
-
|
1046 |
-
} else {
|
1047 |
-
|
1048 |
-
// new empty array ##
|
1049 |
-
$groups = array();
|
1050 |
-
|
1051 |
-
// loop over all groups ##
|
1052 |
-
foreach( $group_ids["groups"] as $group_id ) {
|
1053 |
-
|
1054 |
-
$groups[] = groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
|
1055 |
-
|
1056 |
-
}
|
1057 |
-
|
1058 |
-
// implode it ##
|
1059 |
-
$value = implode( $groups, '|' );
|
1060 |
-
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
} else {
|
1064 |
-
|
1065 |
-
$value = '';
|
1066 |
-
|
1067 |
-
}
|
1068 |
-
|
1069 |
-
}
|
1070 |
-
elseif ( $field == 'bp_latest_update' || $field == 'last_activity' )
|
1071 |
-
{
|
1072 |
-
|
1073 |
-
// https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
|
1074 |
-
$value = bp_get_user_last_activity( $user->ID );
|
1075 |
-
|
1076 |
-
// user or usermeta field ##
|
1077 |
-
}
|
1078 |
-
else
|
1079 |
-
{
|
1080 |
-
|
1081 |
-
// the user_meta key isset ##
|
1082 |
-
if ( isset( $get_user_meta[$field] ) ) {
|
1083 |
-
|
1084 |
-
// take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
|
1085 |
-
$value = $get_user_meta[$field][0];
|
1086 |
-
|
1087 |
-
// standard WP_User value ##
|
1088 |
-
} else {
|
1089 |
-
|
1090 |
-
// use the magically assigned value from WP_Users
|
1091 |
-
$value =isset( $user->{$field} ) ? $user->{$field} : null ;
|
1092 |
-
|
1093 |
-
}
|
1094 |
-
|
1095 |
-
|
1096 |
-
// the $value might be serialized ##
|
1097 |
-
$value = $this->unserialize( $value );
|
1098 |
-
|
1099 |
-
// the value is an array ##
|
1100 |
-
if ( is_array ( $value ) ) {
|
1101 |
-
|
1102 |
-
// recursive implode it ##
|
1103 |
-
$value = $this->recursive_implode( $value );
|
1104 |
-
|
1105 |
-
}
|
1106 |
-
|
1107 |
-
// sanitize ##
|
1108 |
-
#$value = $this->sanitize($value);
|
1109 |
-
|
1110 |
-
}
|
1111 |
-
|
1112 |
-
|
1113 |
-
// correct program value to Program Name ##
|
1114 |
-
if ( $field == 'member_of_club' ) {
|
1115 |
-
|
1116 |
-
$value = get_the_title($value);
|
1117 |
-
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
// sanitize ##
|
1121 |
-
$value = $this->sanitize($value);
|
1122 |
-
|
1123 |
-
// wrap values in quotes and add to array ##
|
1124 |
-
if ( $is_csv ) {
|
1125 |
-
|
1126 |
-
$data[] = '"' . str_replace( '"', '""', $this->special_characters( $value ) ) . '"';
|
1127 |
-
|
1128 |
-
// just add to array ##
|
1129 |
-
} else {
|
1130 |
-
|
1131 |
-
$data[] = $this->special_characters( $value );
|
1132 |
-
}
|
1133 |
-
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
// echo row data ##
|
1137 |
-
echo $pre . implode( $seperator, $data ) . $breaker;
|
1138 |
-
|
1139 |
-
}
|
1140 |
-
|
1141 |
-
// close doc wrapper..
|
1142 |
-
echo $doc_end;
|
1143 |
-
|
1144 |
-
// stop PHP, so file can export correctly ##
|
1145 |
-
exit;
|
1146 |
-
|
1147 |
-
}
|
1148 |
-
|
1149 |
-
|
1150 |
-
/**
|
1151 |
-
* Content of the settings page
|
1152 |
-
*
|
1153 |
-
* @since 0.1
|
1154 |
-
**/
|
1155 |
-
public function users_page()
|
1156 |
-
{
|
1157 |
-
|
1158 |
-
// quick security check ##
|
1159 |
-
if ( ! current_user_can( 'list_users' ) ) {
|
1160 |
-
|
1161 |
-
wp_die( __( 'You do not have sufficient permissions to access this page.', 'export-user-data' ) );
|
1162 |
-
|
1163 |
-
}
|
1164 |
-
|
1165 |
-
// Save settings button was pressed ##
|
1166 |
-
if (
|
1167 |
-
isset( $_POST['save_export'] )
|
1168 |
-
&& check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
|
1169 |
-
) {
|
1170 |
-
|
1171 |
-
// start with an empty variable ##
|
1172 |
-
$save_export = "";
|
1173 |
-
|
1174 |
-
if ( ! empty( $_POST['save_new_export_name'] ) ) {
|
1175 |
-
|
1176 |
-
// assign value ##
|
1177 |
-
$save_export = $_POST['save_new_export_name'];
|
1178 |
-
|
1179 |
-
} elseif ( ! empty( $_POST['export_name'] ) ) {
|
1180 |
-
|
1181 |
-
$save_export = $_POST['export_name'];
|
1182 |
-
|
1183 |
-
}
|
1184 |
-
|
1185 |
-
// clean up $save_export ##
|
1186 |
-
$save_export = sanitize_text_field( $save_export );
|
1187 |
-
|
1188 |
-
// Build array of $options to save and save them ##
|
1189 |
-
if ( isset( $save_export ) ) {
|
1190 |
-
|
1191 |
-
// prepare all array values ##
|
1192 |
-
$usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
|
1193 |
-
$bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
|
1194 |
-
$bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '' ;
|
1195 |
-
$format = isset( $_POST['format'] ) ? $_POST['format'] : '' ;
|
1196 |
-
$role = isset( $_POST['role'] ) ? $_POST['role'] : '' ;
|
1197 |
-
$roles = isset( $_POST['roles'] ) ? $_POST['roles'] : '0' ;
|
1198 |
-
$user_fields = isset( $_POST['user_fields'] ) ? $_POST['user_fields'] : '0' ;
|
1199 |
-
$groups = isset( $_POST['groups'] ) ? $_POST['groups'] : '0' ;
|
1200 |
-
$start_date = isset( $_POST['start_date'] ) ? $_POST['start_date'] : '' ;
|
1201 |
-
$end_date = isset( $_POST['end_date'] ) ? $_POST['end_date'] : '' ;
|
1202 |
-
$limit_offset = isset( $_POST['limit_offset'] ) ? $_POST['limit_offset'] : '' ;
|
1203 |
-
$limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
|
1204 |
-
$updated_since_date = isset ( $_POST['updated_since_date'] ) ? $_POST['updated_since_date'] : '' ;
|
1205 |
-
$field_updated_since = isset ( $_POST['bp_field_updated_since'] ) ? $_POST['bp_field_updated_since'] : '';
|
1206 |
-
|
1207 |
-
// assign all values to an array ##
|
1208 |
-
$save_array = array (
|
1209 |
-
'usermeta_saved_fields' => $usermeta,
|
1210 |
-
'bp_fields_saved_fields' => $bp_fields,
|
1211 |
-
'bp_fields_update_time_saved_fields' => $bp_fields_update,
|
1212 |
-
'role' => $role,
|
1213 |
-
'roles' => $roles,
|
1214 |
-
'user_fields' => $user_fields,
|
1215 |
-
'groups' => $groups,
|
1216 |
-
'start_date' => $start_date,
|
1217 |
-
'end_date' => $end_date,
|
1218 |
-
'limit_offset' => $limit_offset,
|
1219 |
-
'limit_total' => $limit_total,
|
1220 |
-
'updated_since_date' => $updated_since_date,
|
1221 |
-
'field_updated_since' => $field_updated_since,
|
1222 |
-
'format' => $format
|
1223 |
-
);
|
1224 |
-
|
1225 |
-
// store the options, for next load ##
|
1226 |
-
$this->set_user_options( $save_export, $save_array );
|
1227 |
-
|
1228 |
-
// Display the settings the user just saved instead of blanking the form ##
|
1229 |
-
$_POST['load_export'] = 'Load Settings';
|
1230 |
-
$_POST['export_name'] = $save_export;
|
1231 |
-
|
1232 |
-
}
|
1233 |
-
|
1234 |
-
}
|
1235 |
-
|
1236 |
-
// Load settings button was pressed ( or option saved and $_POST variables hijacked )##
|
1237 |
-
if (
|
1238 |
-
isset( $_POST['load_export'] )
|
1239 |
-
&& isset( $_POST['export_name'] )
|
1240 |
-
&& check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
|
1241 |
-
) {
|
1242 |
-
|
1243 |
-
$this->get_user_options_by_export( sanitize_text_field( $_POST['export_name'] ) );
|
1244 |
-
|
1245 |
-
}
|
1246 |
-
|
1247 |
-
// Delete settings button was pressed ##
|
1248 |
-
if (
|
1249 |
-
isset( $_POST['delete_export'] )
|
1250 |
-
&& isset( $_POST['export_name'] )
|
1251 |
-
&& check_admin_referer( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' )
|
1252 |
-
) {
|
1253 |
-
|
1254 |
-
$this->delete_user_options( sanitize_text_field( $_POST['export_name'] ) );
|
1255 |
-
|
1256 |
-
}
|
1257 |
-
|
1258 |
-
// what's in 'this' ? ##
|
1259 |
-
#self:pr( $this );
|
1260 |
-
|
1261 |
-
?>
|
1262 |
-
<div class="wrap">
|
1263 |
-
<h2><?php _e( 'Export User Data', 'export-user-data' ); ?></h2>
|
1264 |
-
<?php
|
1265 |
-
|
1266 |
-
// nothing happening? ##
|
1267 |
-
if ( isset( $_GET['error'] ) ) {
|
1268 |
-
echo '<div class="updated"><p><strong>' . __( 'No users found.', 'export-user-data' ) . '</strong></p></div>';
|
1269 |
-
}
|
1270 |
-
|
1271 |
-
?>
|
1272 |
-
<form method="post" action="" enctype="multipart/form-data">
|
1273 |
-
<?php wp_nonce_field( 'q-eud-export-user-page_export', '_wpnonce-q-eud-export-user-page_export' ); ?>
|
1274 |
-
<table class="form-table">
|
1275 |
-
<?php
|
1276 |
-
|
1277 |
-
// allow admin to select user meta fields to export ##
|
1278 |
-
global $wpdb;
|
1279 |
-
$meta_keys = $wpdb->get_results( "SELECT distinct(meta_key) FROM $wpdb->usermeta" );
|
1280 |
-
|
1281 |
-
// get meta_key value from object ##
|
1282 |
-
$meta_keys = wp_list_pluck( $meta_keys, 'meta_key' );
|
1283 |
-
|
1284 |
-
// let's note some of them odd keys ##
|
1285 |
-
$meta_keys_system = array(
|
1286 |
-
'metaboxhidden',
|
1287 |
-
'activation',
|
1288 |
-
'bp_',
|
1289 |
-
'nav_',
|
1290 |
-
'wp_',
|
1291 |
-
'admin_color',
|
1292 |
-
'wpmudev',
|
1293 |
-
'screen_',
|
1294 |
-
'show_',
|
1295 |
-
'rich_',
|
1296 |
-
'reward_',
|
1297 |
-
'meta-box',
|
1298 |
-
'manageedit',
|
1299 |
-
'edit_',
|
1300 |
-
'closedpostboxes_',
|
1301 |
-
'dismissed_',
|
1302 |
-
'manage',
|
1303 |
-
'comment',
|
1304 |
-
'current',
|
1305 |
-
'incentive_',
|
1306 |
-
'_wdp',
|
1307 |
-
'ssl',
|
1308 |
-
'wdfb',
|
1309 |
-
'users_per_page',
|
1310 |
-
);
|
1311 |
-
|
1312 |
-
// allow array to be filtered ##
|
1313 |
-
$meta_keys_system = apply_filters( 'export_user_data_meta_keys_system', $meta_keys_system );
|
1314 |
-
|
1315 |
-
// test array ##
|
1316 |
-
#echo '<pre>'; var_dump($meta_keys); echo '</pre>';
|
1317 |
-
|
1318 |
-
// check if we got anything ? ##
|
1319 |
-
if ( $meta_keys ) {
|
1320 |
-
|
1321 |
-
?>
|
1322 |
-
<tr valign="top">
|
1323 |
-
<th scope="row">
|
1324 |
-
<label for="q_eud_usermeta"><?php _e( 'User Meta Fields', 'export-user-data' ); ?></label>
|
1325 |
-
<p class="filter" style="margin: 10px 0 0;">
|
1326 |
-
<?php _e('Filter', 'export-user-data'); ?>: <a href="#" class="usermeta-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="usermeta-common"><?php _e('Common', 'export-user-data'); ?></a>
|
1327 |
-
</p>
|
1328 |
-
<p class="filter" style="margin: 10px 0 0;">
|
1329 |
-
<?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
|
1330 |
-
</p>
|
1331 |
-
</th>
|
1332 |
-
<td>
|
1333 |
-
<select multiple="multiple" id="usermeta" name="usermeta[]">
|
1334 |
-
<?php
|
1335 |
-
|
1336 |
-
foreach ( $meta_keys as $key ) {
|
1337 |
-
|
1338 |
-
#echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
|
1339 |
-
|
1340 |
-
// display $key ##
|
1341 |
-
$display_key = $key;
|
1342 |
-
|
1343 |
-
// rename programs field ##
|
1344 |
-
if ( $display_key == 'member_of_club' ){
|
1345 |
-
$display_key = 'program';
|
1346 |
-
}
|
1347 |
-
|
1348 |
-
// tidy ##
|
1349 |
-
$display_key = str_replace( "_", " ", ucwords( $display_key ) );
|
1350 |
-
|
1351 |
-
#echo "<label for='".esc_attr( $key )."' title='".esc_attr( $key )."'><input id='".esc_attr( $key )."' type='checkbox' name='usermeta[]' value='".esc_attr( $key )."'/> $display_key</label><br />";
|
1352 |
-
|
1353 |
-
// class ##
|
1354 |
-
$usermeta_class = 'normal';
|
1355 |
-
|
1356 |
-
foreach ( $meta_keys_system as $drop ) {
|
1357 |
-
|
1358 |
-
if ( strpos( $key, $drop ) !== false ) {
|
1359 |
-
|
1360 |
-
// https://wordpress.org/support/topic/bugfix-numbers-in-export-headers?replies=1
|
1361 |
-
// removed $key = assignment, as not required ##
|
1362 |
-
if ( ( array_search( $key, $meta_keys ) ) !== false ) {
|
1363 |
-
|
1364 |
-
$usermeta_class = 'system';
|
1365 |
-
|
1366 |
-
}
|
1367 |
-
|
1368 |
-
}
|
1369 |
-
|
1370 |
-
}
|
1371 |
-
|
1372 |
-
// print key ##
|
1373 |
-
echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."' class='".$usermeta_class."'>$display_key</option>";
|
1374 |
-
|
1375 |
-
}
|
1376 |
-
?>
|
1377 |
-
</select>
|
1378 |
-
<p class="description"><?php
|
1379 |
-
printf(
|
1380 |
-
__( 'Select the user meta keys to export, use the filters to simplify the list.', 'export-user-data' )
|
1381 |
-
);
|
1382 |
-
?></p>
|
1383 |
-
</td>
|
1384 |
-
</tr>
|
1385 |
-
<?php
|
1386 |
-
|
1387 |
-
} // meta_keys found ##
|
1388 |
-
|
1389 |
-
?>
|
1390 |
-
<?php
|
1391 |
-
|
1392 |
-
// buddypress x profile data ##
|
1393 |
-
if ( function_exists ('bp_is_active') ) {
|
1394 |
-
|
1395 |
-
// grab all buddypress x profile fields ##
|
1396 |
-
$bp_fields = $wpdb->get_results( "SELECT distinct(name) FROM ".$wpdb->base_prefix."bp_xprofile_fields WHERE parent_id = 0" );
|
1397 |
-
|
1398 |
-
// get name value from object ##
|
1399 |
-
$bp_fields = wp_list_pluck( $bp_fields, 'name' );
|
1400 |
-
|
1401 |
-
// test array ##
|
1402 |
-
#echo '<pre>'; var_dump($bp_fields); echo '</pre>';
|
1403 |
-
|
1404 |
-
// allow array to be filtered ##
|
1405 |
-
$bp_fields = apply_filters( 'export_user_data_bp_fields', $bp_fields );
|
1406 |
-
|
1407 |
-
?>
|
1408 |
-
<tr valign="top">
|
1409 |
-
<th scope="row">
|
1410 |
-
<label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields', 'export-user-data' ); ?></label>
|
1411 |
-
<p class="filter" style="margin: 10px 0 0;">
|
1412 |
-
<?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
|
1413 |
-
</p>
|
1414 |
-
</th>
|
1415 |
-
<td>
|
1416 |
-
<select multiple="multiple" id="bp_fields" name="bp_fields[]">
|
1417 |
-
<?php
|
1418 |
-
|
1419 |
-
foreach ( $bp_fields as $key ) {
|
1420 |
-
|
1421 |
-
// tidy up key ##
|
1422 |
-
#$key_tidy = str_replace( ' ', '__', $key );
|
1423 |
-
|
1424 |
-
#echo "<label for='".esc_attr( $key_tidy )."'><input id='".esc_attr( $key_tidy )."' type='checkbox' name='bp_fields[]' value='".esc_attr( $key_tidy )."'/> $key</label><br />";
|
1425 |
-
|
1426 |
-
// print key ##
|
1427 |
-
echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
|
1428 |
-
|
1429 |
-
}
|
1430 |
-
|
1431 |
-
?>
|
1432 |
-
</select>
|
1433 |
-
<p class="description"><?php
|
1434 |
-
printf(
|
1435 |
-
__( 'Select the BuddyPress XProfile keys to export', 'export-user-data' )
|
1436 |
-
);
|
1437 |
-
?></p>
|
1438 |
-
</td>
|
1439 |
-
</tr>
|
1440 |
-
<?php
|
1441 |
-
|
1442 |
-
// allow export of update times ##
|
1443 |
-
|
1444 |
-
?>
|
1445 |
-
<tr valign="top" class="toggleable">
|
1446 |
-
<th scope="row">
|
1447 |
-
<label for="q_eud_xprofile"><?php _e( 'BP xProfile Fields Update Time', 'export-user-data' ); ?></label>
|
1448 |
-
<p class="filter" style="margin: 10px 0 0;">
|
1449 |
-
<?php _e('Select', 'export-user-data'); ?>: <a href="#" class="select-all"><?php _e('All', 'export-user-data'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'export-user-data'); ?></a>
|
1450 |
-
</p>
|
1451 |
-
</th>
|
1452 |
-
<td>
|
1453 |
-
<select multiple="multiple" id="bp_fields_update_time" name="bp_fields_update_time[]">
|
1454 |
-
<?php
|
1455 |
-
|
1456 |
-
foreach ( $bp_fields as $key ) {
|
1457 |
-
|
1458 |
-
echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
|
1459 |
-
|
1460 |
-
}
|
1461 |
-
|
1462 |
-
?>
|
1463 |
-
</select>
|
1464 |
-
<p class="description"><?php
|
1465 |
-
printf(
|
1466 |
-
__( 'Select the BuddyPress XProfile keys updated dates to export', 'export-user-data' )
|
1467 |
-
);
|
1468 |
-
?></p>
|
1469 |
-
</td>
|
1470 |
-
</tr>
|
1471 |
-
|
1472 |
-
<tr valign="top" class="toggleable">
|
1473 |
-
<th scope="row"><label for="groups"><?php _e( 'BP User Groups', 'export-user-data' ); ?></label></th>
|
1474 |
-
<td>
|
1475 |
-
<input id='groups' type='checkbox' name='groups' value='1' <?php checked( isset ( $this->groups ) ? intval ( $this->groups ) : '', 1 ); ?> />
|
1476 |
-
<p class="description"><?php
|
1477 |
-
printf(
|
1478 |
-
__( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
|
1479 |
-
, esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
|
1480 |
-
, 'Codex'
|
1481 |
-
);
|
1482 |
-
?></p>
|
1483 |
-
</td>
|
1484 |
-
</tr>
|
1485 |
-
<?php
|
1486 |
-
|
1487 |
-
} // BP installed and active ##
|
1488 |
-
|
1489 |
-
?>
|
1490 |
-
<tr valign="top" class="toggleable">
|
1491 |
-
<th scope="row"><label for="user_fields"><?php _e( 'Standard User Fields', 'export-user-data' ); ?></label></th>
|
1492 |
-
<td>
|
1493 |
-
<input id='user_fields' type='checkbox' name='user_fields' value='1' <?php checked( isset ( $this->user_fields ) ? intval ( $this->user_fields ) : '', 1 ); ?> />
|
1494 |
-
<p class="description"><?php
|
1495 |
-
|
1496 |
-
#$this->log( 'user_fields: '.$this->user_fields );
|
1497 |
-
#echo 'user_fields: '. $this->user_fields;
|
1498 |
-
|
1499 |
-
printf(
|
1500 |
-
__( 'Include Standard user profile fields, such as user_login. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
|
1501 |
-
, esc_html('https://codex.wordpress.org/Database_Description#Table:_wp_users')
|
1502 |
-
, 'Codex'
|
1503 |
-
);
|
1504 |
-
|
1505 |
-
?></p>
|
1506 |
-
</td>
|
1507 |
-
</tr>
|
1508 |
-
|
1509 |
-
<tr valign="top" class="toggleable">
|
1510 |
-
<th scope="row"><label for="q_eud_users_role"><?php _e( 'Role', 'export-user-data' ); ?></label></th>
|
1511 |
-
<td>
|
1512 |
-
<select name="role" id="q_eud_users_role">
|
1513 |
-
<?php
|
1514 |
-
|
1515 |
-
echo '<option value="">' . __( 'All Roles', 'export-user-data' ) . '</option>';
|
1516 |
-
global $wp_roles;
|
1517 |
-
|
1518 |
-
foreach ( $wp_roles->role_names as $role => $name ) {
|
1519 |
-
|
1520 |
-
if ( isset ( $this->role ) && ( $this->role == $role ) ) {
|
1521 |
-
|
1522 |
-
echo "\n\t<option selected value='" . esc_attr( $role ) . "'>$name</option>";
|
1523 |
-
|
1524 |
-
} else {
|
1525 |
-
|
1526 |
-
echo "\n\t<option value='" . esc_attr( $role ) . "'>$name</option>";
|
1527 |
-
|
1528 |
-
}
|
1529 |
-
}
|
1530 |
-
|
1531 |
-
|
1532 |
-
?>
|
1533 |
-
</select>
|
1534 |
-
<p class="description"><?php
|
1535 |
-
printf(
|
1536 |
-
__( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
|
1537 |
-
, esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
|
1538 |
-
, 'Codex'
|
1539 |
-
);
|
1540 |
-
?></p>
|
1541 |
-
</td>
|
1542 |
-
</tr>
|
1543 |
-
|
1544 |
-
<tr valign="top" class="toggleable">
|
1545 |
-
<th scope="row"><label for="roles"><?php _e( 'User Roles', 'export-user-data' ); ?></label></th>
|
1546 |
-
<td>
|
1547 |
-
<input id='roles' type='checkbox' name='roles' value='1' <?php checked( isset ( $this->roles ) ? intval ( $this->roles ) : '', 1 ); ?> />
|
1548 |
-
<p class="description"><?php
|
1549 |
-
printf(
|
1550 |
-
__( 'Include all of the users <a href="%s" target="_blank">%s</a>', 'export-user-data' )
|
1551 |
-
, esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
|
1552 |
-
, 'Roles'
|
1553 |
-
);
|
1554 |
-
?></p>
|
1555 |
-
</td>
|
1556 |
-
</tr>
|
1557 |
-
<?php
|
1558 |
-
|
1559 |
-
// clubs ? ##
|
1560 |
-
if ( post_type_exists( 'club' ) ) {
|
1561 |
-
|
1562 |
-
?>
|
1563 |
-
<tr valign="top" class="toggleable">
|
1564 |
-
<th scope="row"><label for="q_eud_users_program"><?php _e( 'Programs', 'export-user-data' ); ?></label></th>
|
1565 |
-
<td>
|
1566 |
-
<select name="program" id="q_eud_users_program">
|
1567 |
-
<?php
|
1568 |
-
|
1569 |
-
echo '<option value="">' . __( 'All Programs', 'export-user-data' ) . '</option>';
|
1570 |
-
|
1571 |
-
$clubs_array = get_posts(array( 'post_type'=> 'club', 'posts_per_page' => -1 )); // grab all posts of type "club" ##
|
1572 |
-
|
1573 |
-
foreach ( $clubs_array as $c ) { // loop over all clubs ##
|
1574 |
-
|
1575 |
-
#$clubs[$c->ID] = $c; // grab club ID ##
|
1576 |
-
echo "\n\t<option value='" . esc_attr( $c->ID ) . "'>$c->post_title</option>";
|
1577 |
-
|
1578 |
-
}
|
1579 |
-
|
1580 |
-
?>
|
1581 |
-
</select>
|
1582 |
-
</td>
|
1583 |
-
</tr>
|
1584 |
-
<?php
|
1585 |
-
|
1586 |
-
} // clubs ##
|
1587 |
-
|
1588 |
-
?>
|
1589 |
-
<tr valign="top" class="toggleable">
|
1590 |
-
<th scope="row"><label><?php _e( 'Registered', 'export-user-data' ); ?></label></th>
|
1591 |
-
<td>
|
1592 |
-
<input type="text" id="q_eud_users_start_date" name="start_date" value="<?php echo $this->start_date; ?>" class="start-datepicker" />
|
1593 |
-
<input type="text" id="q_eud_users_end_date" name="end_date" value="<?php echo $this->end_date; ?>" class="end-datepicker" />
|
1594 |
-
<p class="description"><?php
|
1595 |
-
printf(
|
1596 |
-
__( 'Pick a start and end user registration date to limit the results.', 'export-user-data' )
|
1597 |
-
);
|
1598 |
-
?></p>
|
1599 |
-
</td>
|
1600 |
-
</tr>
|
1601 |
-
|
1602 |
-
<tr valign="top" class="toggleable">
|
1603 |
-
<th scope="row"><label><?php _e( 'Limit Range', 'export-user-data' ); ?></label></th>
|
1604 |
-
<td>
|
1605 |
-
<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' ); ?>">
|
1606 |
-
<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' ); ?>">
|
1607 |
-
<p class="description"><?php
|
1608 |
-
printf(
|
1609 |
-
__( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', 'export-user-data' )
|
1610 |
-
, esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
|
1611 |
-
, 'Codex'
|
1612 |
-
);
|
1613 |
-
?></p>
|
1614 |
-
</td>
|
1615 |
-
</tr>
|
1616 |
-
|
1617 |
-
<tr valign="top" class="toggleable">
|
1618 |
-
<th scope="row"><label><?php _e( 'Updated Since', 'export-user-data' ); ?></label></th>
|
1619 |
-
<td>
|
1620 |
-
<input type="text" id="q_eud_updated_since_date" name="updated_since_date" value="<?php echo $this->updated_since_date; ?>" class="updated-datepicker" />
|
1621 |
-
<select id="bp_field_updated_since" name="bp_field_updated_since">
|
1622 |
-
<?php
|
1623 |
-
|
1624 |
-
foreach ( $bp_fields as $key ) {
|
1625 |
-
if ( $this->field_updated_since == $key ) {
|
1626 |
-
echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."' selected>$key</option>";
|
1627 |
-
} else {
|
1628 |
-
echo "<option value='".esc_attr( $key )."' title='".esc_attr( $key )."'>$key</option>";
|
1629 |
-
}
|
1630 |
-
}
|
1631 |
-
|
1632 |
-
?>
|
1633 |
-
</select>
|
1634 |
-
|
1635 |
-
<p class="description"><?php
|
1636 |
-
printf(
|
1637 |
-
__( 'Limit the results to users who have updated this extended profile field after this date.', 'export-user-data' )
|
1638 |
-
);
|
1639 |
-
?></p>
|
1640 |
-
</td>
|
1641 |
-
</tr>
|
1642 |
-
|
1643 |
-
<tr valign="top">
|
1644 |
-
<th scope="row"><label for="q_eud_users_format"><?php _e( 'Format', 'export-user-data' ); ?></label></th>
|
1645 |
-
<td>
|
1646 |
-
<select name="format" id="q_eud_users_format">
|
1647 |
-
<?php
|
1648 |
-
if ( isset ( $this->format ) && ( $this->format == 'excel' ) ) {
|
1649 |
-
echo '<option selected value="excel">' . __( 'Excel', 'export-user-data' ) . '</option>';
|
1650 |
-
} else {
|
1651 |
-
echo '<option value="excel">' . __( 'Excel', 'export-user-data' ) . '</option>';
|
1652 |
-
}
|
1653 |
-
if ( isset ( $this->format ) && ( $this->format == 'csv' ) ) {
|
1654 |
-
echo '<option selected value="csv">' . __( 'CSV', 'export-user-data' ) . '</option>';
|
1655 |
-
} else {
|
1656 |
-
echo '<option value="csv">' . __( 'CSV', 'export-user-data' ) . '</option>';
|
1657 |
-
}
|
1658 |
-
?>
|
1659 |
-
</select>
|
1660 |
-
<p class="description"><?php
|
1661 |
-
printf(
|
1662 |
-
__( 'Select the format for the export file.', 'export-user-data' )
|
1663 |
-
);
|
1664 |
-
?></p>
|
1665 |
-
</td>
|
1666 |
-
</tr>
|
1667 |
-
|
1668 |
-
<tr valign="top" class="remember">
|
1669 |
-
<th scope="row"><label for="q_eud_save_options"><?php _e( 'Stored Options', 'export-user-data' ); ?></label></th>
|
1670 |
-
<td>
|
1671 |
-
|
1672 |
-
<div class="row">
|
1673 |
-
<input type="text" class="regular-text" name="save_new_export_name" id="q_eud_save_options_new_export" placeholder="<?php _e( 'Export Name', 'export-user-data' ); ?>" value="<?php echo isset( $_POST['export_name'] ) ? $_POST['export_name'] : '' ; ?>">
|
1674 |
-
<input type="submit" id="save_export" class="button-primary" name="save_export" value="<?php _e( 'Save', 'export-user-data' ); ?>" />
|
1675 |
-
</div>
|
1676 |
-
<?php
|
1677 |
-
|
1678 |
-
// check if the user has any saved exports ##
|
1679 |
-
if ( $this->get_user_options() ) {
|
1680 |
-
|
1681 |
-
?>
|
1682 |
-
<div class="row">
|
1683 |
-
<select name="export_name" id="q_eud_save_options" class="regular-text">
|
1684 |
-
<?php
|
1685 |
-
|
1686 |
-
// loop over each saved export ##
|
1687 |
-
foreach( $this->get_user_options() as $export ) {
|
1688 |
-
|
1689 |
-
// select Loaded export name, if selected ##
|
1690 |
-
if (
|
1691 |
-
isset( $_POST['load_export'] )
|
1692 |
-
&& isset( $_POST['export_name'] )
|
1693 |
-
&& ( $_POST['export_name'] == $export )
|
1694 |
-
) {
|
1695 |
-
|
1696 |
-
echo "<option selected value='$export'>$export</option>";
|
1697 |
-
|
1698 |
-
// just list previous export name ##
|
1699 |
-
} else {
|
1700 |
-
|
1701 |
-
echo "<option value='$export'>$export</option>";
|
1702 |
-
|
1703 |
-
}
|
1704 |
-
|
1705 |
-
}
|
1706 |
-
|
1707 |
-
?>
|
1708 |
-
</select>
|
1709 |
-
|
1710 |
-
<input type="submit" id="load_export" class="button-primary" name="load_export" value="<?php _e( 'Load', 'export-user-data' ); ?>" />
|
1711 |
-
<input type="submit" id="delete_export" class="button-primary" name="delete_export" value="<?php _e( 'Delete', 'export-user-data' ); ?>" />
|
1712 |
-
<?php
|
1713 |
-
|
1714 |
-
}
|
1715 |
-
|
1716 |
-
?>
|
1717 |
-
</div>
|
1718 |
-
<p class="description"><?php _e( 'Save, load or delete your stored export options.', 'export-user-data' ); ?></p>
|
1719 |
-
|
1720 |
-
</td>
|
1721 |
-
</tr>
|
1722 |
-
|
1723 |
-
<tr valign="top">
|
1724 |
-
<th scope="row">
|
1725 |
-
<label for="q_eud_xprofile"><?php _e( 'Advanced Options', 'export-user-data' ); ?></label>
|
1726 |
-
</th>
|
1727 |
-
<td>
|
1728 |
-
<div class="toggle">
|
1729 |
-
<a href="#"><?php _e( 'Show', 'export-user-data' ); ?></a>
|
1730 |
-
</div>
|
1731 |
-
</td>
|
1732 |
-
</tr>
|
1733 |
-
|
1734 |
-
</table>
|
1735 |
-
<p class="submit">
|
1736 |
-
<input type="hidden" name="_wp_http_referer" value="<?php echo esc_url( $_SERVER['REQUEST_URI'] ); ?>" />
|
1737 |
-
<input type="submit" class="button-primary" value="<?php _e( 'Run Export', 'export-user-data' ); ?>" />
|
1738 |
-
</p>
|
1739 |
-
</form>
|
1740 |
-
</div>
|
1741 |
-
|
1742 |
-
<?php
|
1743 |
-
}
|
1744 |
-
|
1745 |
-
|
1746 |
-
/**
|
1747 |
-
* Inline jQuery
|
1748 |
-
* @since 0.8.2
|
1749 |
-
*/
|
1750 |
-
public function jquery()
|
1751 |
-
{
|
1752 |
-
|
1753 |
-
// load the scripts on only the plugin admin page
|
1754 |
-
if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
|
1755 |
-
|
1756 |
-
?>
|
1757 |
-
<script>
|
1758 |
-
|
1759 |
-
// lazy load in some jQuery validation ##
|
1760 |
-
jQuery(document).ready(function($) {
|
1761 |
-
|
1762 |
-
// build super multiselect ##
|
1763 |
-
jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
|
1764 |
-
|
1765 |
-
//Select any fields from saved settings ##
|
1766 |
-
jQuery('#usermeta').multiSelect('select',([<?php echo( $this->quote_array( $this->usermeta_saved_fields ) ); ?>]));
|
1767 |
-
jQuery('#bp_fields').multiSelect('select',([<?php echo( $this->quote_array($this->bp_fields_saved_fields ) ); ?>]));
|
1768 |
-
jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( $this->quote_array( $this->bp_fields_update_time_saved_fields ) ); ?>]));
|
1769 |
-
|
1770 |
-
// show only common ##
|
1771 |
-
jQuery('.usermeta-common').click(function(e){
|
1772 |
-
e.preventDefault();
|
1773 |
-
jQuery('#ms-usermeta .ms-selectable li.system').hide();
|
1774 |
-
});
|
1775 |
-
|
1776 |
-
// show all ##
|
1777 |
-
jQuery('.usermeta-all').click(function(e){
|
1778 |
-
e.preventDefault();
|
1779 |
-
jQuery('#ms-usermeta .ms-selectable li').show();
|
1780 |
-
});
|
1781 |
-
|
1782 |
-
// select all ##
|
1783 |
-
jQuery('.select-all').click(function(e){
|
1784 |
-
e.preventDefault();
|
1785 |
-
jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
|
1786 |
-
});
|
1787 |
-
|
1788 |
-
// select none ##
|
1789 |
-
jQuery('.select-none').click(function(e){
|
1790 |
-
e.preventDefault();
|
1791 |
-
jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'deselect_all' );
|
1792 |
-
});
|
1793 |
-
|
1794 |
-
|
1795 |
-
// validate number inputs ##
|
1796 |
-
$("input.numeric").blur(function() {
|
1797 |
-
|
1798 |
-
//console.log("you entered "+ $(this).val());
|
1799 |
-
|
1800 |
-
if ( $(this).val() && ! $.isNumeric( $(this).val() ) ) {
|
1801 |
-
|
1802 |
-
//console.log("this IS NOT a number");
|
1803 |
-
$(this).css({ 'background': 'red', 'color': 'white' }); // highlight error ##
|
1804 |
-
$("p.submit .button-primary").attr('disabled','disabled'); // disable submit ##
|
1805 |
-
|
1806 |
-
} else {
|
1807 |
-
|
1808 |
-
$(this).css({ 'background': 'white', 'color': '#333' }); // remove error highlighting ##
|
1809 |
-
$("p.submit .button-primary").removeAttr('disabled'); // enable submit ##
|
1810 |
-
|
1811 |
-
}
|
1812 |
-
|
1813 |
-
});
|
1814 |
-
|
1815 |
-
// toggle advanced options ##
|
1816 |
-
jQuery(".toggle a").click( function(e) {
|
1817 |
-
e.preventDefault();
|
1818 |
-
$toggleable = jQuery("tr.toggleable");
|
1819 |
-
$toggleable.toggle();
|
1820 |
-
if ( $toggleable.is(":visible") ) {
|
1821 |
-
jQuery(this).text("<?php _e( 'Hide', 'export-user-data' ); ?>");
|
1822 |
-
} else {
|
1823 |
-
jQuery(this).text("<?php _e( 'Show', 'export-user-data' ); ?>");
|
1824 |
-
}
|
1825 |
-
});
|
1826 |
-
|
1827 |
-
// validate save button ##
|
1828 |
-
jQuery("#save_export").click( function(e) {
|
1829 |
-
|
1830 |
-
// grab the value of the input ##
|
1831 |
-
var q_eud_save_options_new_export = jQuery('#q_eud_save_options_new_export').val();
|
1832 |
-
|
1833 |
-
if ( ! q_eud_save_options_new_export || q_eud_save_options_new_export == '' ) {
|
1834 |
-
|
1835 |
-
e.preventDefault(); // stop things here ##
|
1836 |
-
jQuery('#q_eud_save_options_new_export').addClass("error");
|
1837 |
-
|
1838 |
-
}
|
1839 |
-
|
1840 |
-
});
|
1841 |
-
|
1842 |
-
// remove validation on focus ##
|
1843 |
-
jQuery("body").on( 'focus', '#q_eud_save_options_new_export', function(e) {
|
1844 |
-
|
1845 |
-
jQuery(this).removeClass("error");
|
1846 |
-
|
1847 |
-
});
|
1848 |
-
|
1849 |
-
<?php
|
1850 |
-
|
1851 |
-
// method returns an object with "first" & "last" keys ##
|
1852 |
-
$dates = $this->get_user_registered_dates();
|
1853 |
-
|
1854 |
-
// get date format from WP settings #
|
1855 |
-
$date_format = 'yy-mm-dd' ; // get_option('date_format') ? get_option('date_format') : 'yy-mm-dd' ;
|
1856 |
-
$start_of_week = get_option('start_of_week') ? get_option('start_of_week') : 'yy-mm-dd' ;
|
1857 |
-
#$this->log( 'Date format: '.$date_format );
|
1858 |
-
|
1859 |
-
?>
|
1860 |
-
|
1861 |
-
// start date picker ##
|
1862 |
-
jQuery('.start-datepicker').datepicker( {
|
1863 |
-
dateFormat : '<?php echo $date_format; ?>',
|
1864 |
-
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
1865 |
-
maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
|
1866 |
-
firstDay : '<?php echo $start_of_week; ?>'
|
1867 |
-
} );
|
1868 |
-
|
1869 |
-
// end date picker ##
|
1870 |
-
jQuery('.end-datepicker').datepicker( {
|
1871 |
-
dateFormat : '<?php echo $date_format; ?>',
|
1872 |
-
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
1873 |
-
maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
|
1874 |
-
firstDay : '<?php echo $start_of_week; ?>'
|
1875 |
-
} );
|
1876 |
-
|
1877 |
-
// end date picker ##
|
1878 |
-
// might want to set minDate to something else, but not sure
|
1879 |
-
// what would be best for everyone
|
1880 |
-
jQuery('.updated-datepicker').datepicker( {
|
1881 |
-
dateFormat : '<?php echo $date_format; ?>',
|
1882 |
-
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
1883 |
-
maxDate : '0',
|
1884 |
-
firstDay : '<?php echo $start_of_week; ?>'
|
1885 |
-
} );
|
1886 |
-
|
1887 |
-
});
|
1888 |
-
|
1889 |
-
</script>
|
1890 |
-
<?php
|
1891 |
-
}
|
1892 |
-
|
1893 |
-
}
|
1894 |
-
|
1895 |
-
|
1896 |
-
/**
|
1897 |
-
* Inline CSS
|
1898 |
-
* @since 0.8.2
|
1899 |
-
*/
|
1900 |
-
public function css()
|
1901 |
-
{
|
1902 |
-
|
1903 |
-
// load the scripts on only the plugin admin page
|
1904 |
-
if (isset( $_GET['page'] ) && ( $_GET['page'] == 'export-user-data' ) ) {
|
1905 |
-
?>
|
1906 |
-
<style>
|
1907 |
-
.toggleable { display: none; }
|
1908 |
-
.hidden { display: none; }
|
1909 |
-
</style>
|
1910 |
-
<?php
|
1911 |
-
}
|
1912 |
-
|
1913 |
-
}
|
1914 |
-
|
1915 |
-
|
1916 |
-
/**
|
1917 |
-
* Data to exclude from export
|
1918 |
-
*/
|
1919 |
-
protected function get_exclude_fields()
|
1920 |
-
{
|
1921 |
-
|
1922 |
-
$exclude_fields = array (
|
1923 |
-
'user_pass'
|
1924 |
-
, 'q_eud_exports'
|
1925 |
-
#, 'user_activation_key'
|
1926 |
-
);
|
1927 |
-
|
1928 |
-
return apply_filters( 'export_user_data_exclude_fields', $exclude_fields );
|
1929 |
-
|
1930 |
-
}
|
1931 |
-
|
1932 |
-
|
1933 |
-
/**
|
1934 |
-
* Get the array of standard WP_User fields to return
|
1935 |
-
*/
|
1936 |
-
protected function get_user_fields()
|
1937 |
-
{
|
1938 |
-
|
1939 |
-
// standard wp_users fields ##
|
1940 |
-
if ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) {
|
1941 |
-
|
1942 |
-
// debug ##
|
1943 |
-
#$this->log( 'full' );
|
1944 |
-
|
1945 |
-
// exportable user data ##
|
1946 |
-
$user_fields = array(
|
1947 |
-
'ID'
|
1948 |
-
, 'user_login'
|
1949 |
-
#, 'user_pass'
|
1950 |
-
, 'user_nicename'
|
1951 |
-
, 'user_email'
|
1952 |
-
, 'user_url'
|
1953 |
-
, 'user_registered'
|
1954 |
-
#, 'user_activation_key'
|
1955 |
-
, 'user_status'
|
1956 |
-
, 'display_name'
|
1957 |
-
);
|
1958 |
-
|
1959 |
-
} else {
|
1960 |
-
|
1961 |
-
// debug ##
|
1962 |
-
#$this->log( 'reduced' );
|
1963 |
-
|
1964 |
-
// just return the user ID
|
1965 |
-
$user_fields = array(
|
1966 |
-
'ID'
|
1967 |
-
);
|
1968 |
-
|
1969 |
-
}
|
1970 |
-
|
1971 |
-
// kick back values ##
|
1972 |
-
return apply_filters( 'export_user_data_user_fields', $user_fields );
|
1973 |
-
|
1974 |
-
}
|
1975 |
-
|
1976 |
-
|
1977 |
-
/**
|
1978 |
-
* Get the array of special user fields to return
|
1979 |
-
*/
|
1980 |
-
protected function get_special_fields()
|
1981 |
-
{
|
1982 |
-
|
1983 |
-
// exportable user data ##
|
1984 |
-
$special_fields = array(
|
1985 |
-
# 'roles' // list of WP Roles
|
1986 |
-
#, 'groups' // BP Groups
|
1987 |
-
);
|
1988 |
-
|
1989 |
-
// should we allow groups ##
|
1990 |
-
if ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] ) {
|
1991 |
-
|
1992 |
-
$special_fields[] = 'groups'; // add groups ##
|
1993 |
-
|
1994 |
-
}
|
1995 |
-
|
1996 |
-
// should we allow groups ##
|
1997 |
-
if ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] ) {
|
1998 |
-
|
1999 |
-
$special_fields[] = 'roles'; // add groups ##
|
2000 |
-
|
2001 |
-
}
|
2002 |
-
|
2003 |
-
// kick back the array ##
|
2004 |
-
return apply_filters( 'export_user_data_special_fields', $special_fields );
|
2005 |
-
|
2006 |
-
}
|
2007 |
-
|
2008 |
-
|
2009 |
-
/*
|
2010 |
-
* Pre User Query
|
2011 |
-
*/
|
2012 |
-
public function pre_user_query( $user_search )
|
2013 |
-
{
|
2014 |
-
|
2015 |
-
global $wpdb;
|
2016 |
-
|
2017 |
-
$where = '';
|
2018 |
-
|
2019 |
-
if ( ! empty( $_POST['start_date'] ) ) {
|
2020 |
-
|
2021 |
-
$date = new DateTime( sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
|
2022 |
-
$date_formatted = $date->format( 'Y-m-d H:i:s' );
|
2023 |
-
|
2024 |
-
$where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
|
2025 |
-
|
2026 |
-
}
|
2027 |
-
if ( ! empty( $_POST['end_date'] ) ) {
|
2028 |
-
|
2029 |
-
$date = new DateTime( sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
|
2030 |
-
$date_formatted = $date->format( 'Y-m-d H:i:s' );
|
2031 |
-
|
2032 |
-
$where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
|
2033 |
-
|
2034 |
-
}
|
2035 |
-
|
2036 |
-
// search by last update time of BP extended fields ##
|
2037 |
-
if (
|
2038 |
-
( isset ($_POST['updated_since_date'] ) && $_POST['updated_since_date'] != '' )
|
2039 |
-
&& (isset ($_POST['bp_field_updated_since'] ) && $_POST['bp_field_updated_since'] != '' )
|
2040 |
-
) {
|
2041 |
-
|
2042 |
-
$last_updated_date = new DateTime( sanitize_text_field ( $_POST['updated_since_date'] ) . ' 00:00:00' );
|
2043 |
-
$this->updated_since_date = $last_updated_date->format( 'Y-m-d H:i:s' );
|
2044 |
-
$this->field_updated_since = sanitize_text_field ( $_POST['bp_field_updated_since'] );
|
2045 |
-
$field_updated_since_id = BP_Xprofile_Field::get_id_from_name( $this->field_updated_since );
|
2046 |
-
$user_search->query_from .= " JOIN `wp_bp_xprofile_data` XP ON XP.user_id = wp_users.ID ";
|
2047 |
-
$where .= $wpdb->prepare( " AND XP.field_id = %s AND XP.last_updated >= %s", $field_updated_since_id, $this->updated_since_date );
|
2048 |
-
|
2049 |
-
}
|
2050 |
-
|
2051 |
-
if ( ! empty( $where ) ) {
|
2052 |
-
|
2053 |
-
$user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
|
2054 |
-
|
2055 |
-
}
|
2056 |
-
|
2057 |
-
#wp_die( $this->pr( $user_search ) );
|
2058 |
-
return $user_search;
|
2059 |
-
|
2060 |
-
}
|
2061 |
-
|
2062 |
-
|
2063 |
-
/**
|
2064 |
-
* Export Date Options
|
2065 |
-
*
|
2066 |
-
* @since 0.9.6
|
2067 |
-
* @global type $wpdb
|
2068 |
-
* @return Array of objects
|
2069 |
-
*/
|
2070 |
-
protected function get_user_registered_dates()
|
2071 |
-
{
|
2072 |
-
|
2073 |
-
// invite in global objects ##
|
2074 |
-
global $wpdb;
|
2075 |
-
|
2076 |
-
// query user table for oldest and newest registration ##
|
2077 |
-
$range =
|
2078 |
-
$wpdb->get_results (
|
2079 |
-
#$wpdb->prepare (
|
2080 |
-
"
|
2081 |
-
SELECT
|
2082 |
-
MIN( user_registered ) AS first,
|
2083 |
-
MAX( user_registered ) AS last
|
2084 |
-
FROM
|
2085 |
-
{$wpdb->users}
|
2086 |
-
"
|
2087 |
-
#)
|
2088 |
-
);
|
2089 |
-
|
2090 |
-
return $range;
|
2091 |
-
|
2092 |
-
}
|
2093 |
-
|
2094 |
-
|
2095 |
-
/**
|
2096 |
-
* Quote array elements and separate with commas
|
2097 |
-
*
|
2098 |
-
* @since 0.9.6
|
2099 |
-
* @return String
|
2100 |
-
*/
|
2101 |
-
protected function quote_array( $array )
|
2102 |
-
{
|
2103 |
-
|
2104 |
-
$prefix = ''; // starts empty ##
|
2105 |
-
$elementlist = '';
|
2106 |
-
if ( is_array( $array ) ) {
|
2107 |
-
foreach( $array as $element ) {
|
2108 |
-
$elementlist .= $prefix . "'" . $element . "'";
|
2109 |
-
$prefix = ','; // prefix all remaining items with a comma ##
|
2110 |
-
}
|
2111 |
-
}
|
2112 |
-
|
2113 |
-
// kick back string to function caller ##
|
2114 |
-
return( $elementlist );
|
2115 |
-
|
2116 |
-
}
|
2117 |
-
|
2118 |
-
|
2119 |
-
/**
|
2120 |
-
* Recursively implodes an array
|
2121 |
-
*
|
2122 |
-
* @since 1.0.1
|
2123 |
-
* @access public
|
2124 |
-
* @param array $array multi-dimensional array to recursively implode
|
2125 |
-
* @param string $glue value that glues elements together
|
2126 |
-
* @param bool $include_keys include keys before their values
|
2127 |
-
* @param bool $trim_all trim ALL whitespace from string
|
2128 |
-
* @return string imploded array
|
2129 |
-
*/
|
2130 |
-
protected function recursive_implode( $array, $return = null, $glue = '|' )
|
2131 |
-
{
|
2132 |
-
|
2133 |
-
// unserialize ##
|
2134 |
-
$array = $this->unserialize( $array );
|
2135 |
-
|
2136 |
-
// kick it back ##
|
2137 |
-
if ( is_null ( $return ) && ! is_array( $array ) ) {
|
2138 |
-
|
2139 |
-
return $array;
|
2140 |
-
|
2141 |
-
}
|
2142 |
-
|
2143 |
-
// empty return ##
|
2144 |
-
if ( is_null ( $return ) ) {
|
2145 |
-
|
2146 |
-
$return = '';
|
2147 |
-
|
2148 |
-
} else {
|
2149 |
-
|
2150 |
-
if ( "||" == $glue ) {
|
2151 |
-
|
2152 |
-
$glue = '|||';
|
2153 |
-
|
2154 |
-
} else if ( "|" == $glue ) {
|
2155 |
-
|
2156 |
-
$glue = '||';
|
2157 |
-
|
2158 |
-
}
|
2159 |
-
|
2160 |
-
}
|
2161 |
-
|
2162 |
-
// loop ##
|
2163 |
-
foreach( $array as $key => $value ) {
|
2164 |
-
|
2165 |
-
// unserialize ##
|
2166 |
-
$value = $this->unserialize( $value );
|
2167 |
-
|
2168 |
-
if( is_array( $value ) ) {
|
2169 |
-
|
2170 |
-
$return .= $glue . $key . $glue . $this->recursive_implode( $value, $return, $glue );
|
2171 |
-
|
2172 |
-
} else {
|
2173 |
-
|
2174 |
-
$return .= $glue . $key . $glue . $value;
|
2175 |
-
|
2176 |
-
}
|
2177 |
-
|
2178 |
-
}
|
2179 |
-
|
2180 |
-
// Removes first $glue from string ##
|
2181 |
-
if ( $glue && $return && $return[0] == '|' ) {
|
2182 |
-
|
2183 |
-
$return = ltrim ( $return, '|' );
|
2184 |
-
|
2185 |
-
}
|
2186 |
-
|
2187 |
-
// Trim ALL whitespace ##
|
2188 |
-
if ( $return ) {
|
2189 |
-
|
2190 |
-
$return = preg_replace( "/(\s)/ixsm", '', $return );
|
2191 |
-
|
2192 |
-
}
|
2193 |
-
|
2194 |
-
// kick it back ##
|
2195 |
-
return $return;
|
2196 |
-
|
2197 |
-
}
|
2198 |
-
|
2199 |
-
|
2200 |
-
/**
|
2201 |
-
* Save Unserializer
|
2202 |
-
*
|
2203 |
-
* @since 1.1.4
|
2204 |
-
*/
|
2205 |
-
protected function unserialize( $value )
|
2206 |
-
{
|
2207 |
-
|
2208 |
-
// the $value is serialized ##
|
2209 |
-
if ( is_serialized( $value ) ) {
|
2210 |
-
|
2211 |
-
// unserliaze to new variable ##
|
2212 |
-
$unserialized = @unserialize( $value );
|
2213 |
-
|
2214 |
-
// test if unserliazing produced errors ##
|
2215 |
-
if ( $unserialized !== false || $value == 'b:0;' ) {
|
2216 |
-
|
2217 |
-
#$value = 'UNSERIALIZED_'.$unserialized;
|
2218 |
-
$value = $unserialized;
|
2219 |
-
|
2220 |
-
} else {
|
2221 |
-
|
2222 |
-
// failed to unserialize - data potentially corrupted in db ##
|
2223 |
-
#$value = 'NOT_SERIALIZED_'.$value;
|
2224 |
-
$value = $value;
|
2225 |
-
|
2226 |
-
}
|
2227 |
-
|
2228 |
-
}
|
2229 |
-
|
2230 |
-
// kick it back ##
|
2231 |
-
return $value;
|
2232 |
-
|
2233 |
-
}
|
2234 |
-
|
2235 |
-
|
2236 |
-
/**
|
2237 |
-
* Encode special characters
|
2238 |
-
*
|
2239 |
-
* @param type $string
|
2240 |
-
* @return string Encoding string
|
2241 |
-
* @since 1.2.3
|
2242 |
-
*/
|
2243 |
-
protected function special_characters( $string = null )
|
2244 |
-
{
|
2245 |
-
|
2246 |
-
// sanity check ##
|
2247 |
-
if ( is_null( $string ) ) {
|
2248 |
-
|
2249 |
-
return false;
|
2250 |
-
|
2251 |
-
}
|
2252 |
-
|
2253 |
-
// kick it back in a nicer format ##
|
2254 |
-
return htmlentities( $string, ENT_COMPAT, 'UTF-8' );
|
2255 |
-
|
2256 |
-
}
|
2257 |
-
|
2258 |
-
|
2259 |
-
}
|
2260 |
-
|
2261 |
-
// hook plugin to workdpress action - defined in class ##
|
2262 |
-
add_action( Q_EUD_HOOK, 'q_export_user_data', Q_EUD_PRIORITY );
|
2263 |
-
/**
|
2264 |
-
* Instatiate class and load up schortcode
|
2265 |
-
*
|
2266 |
-
* @since 1.2.8
|
2267 |
-
* @return void
|
2268 |
-
*/
|
2269 |
-
function q_export_user_data()
|
2270 |
-
{
|
2271 |
-
|
2272 |
-
// admin only ##
|
2273 |
-
if ( ! is_admin() ) { return false; }
|
2274 |
-
|
2275 |
-
// instatiate class ##
|
2276 |
-
$export_user_data = new Q_Export_User_Data();
|
2277 |
-
|
2278 |
-
// hook into wp fitlers and actions ##
|
2279 |
-
$export_user_data->run_hooks();
|
2280 |
-
|
2281 |
}
|
2282 |
|
2283 |
-
|
2284 |
-
}
|
1 |
<?php
|
2 |
|
3 |
/*
|
4 |
+
* Plugin Name: Export User Date
|
5 |
+
* Description: Export User data and metadata.
|
6 |
+
* Version: 2.0.1
|
7 |
+
* Author: Q Studio
|
8 |
+
* Author URI: http://qstudio.us/
|
9 |
+
* License: GPL2
|
10 |
+
* Class: q_report
|
11 |
+
* Text Domain: q-report
|
12 |
+
* GitHub Plugin URI: qstudio/q-report
|
13 |
*/
|
14 |
|
15 |
+
/*
|
16 |
+
This plugin will add a "Report" sub menu to the users tab and provide a screen which lists a sent of pre-built report buttons - in some cases with options or filtered by program
|
17 |
+
Exports will print to the screen first - and then have a "Download" button to export csv / xls formatted data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
+
- rebuild export user data with filters, defaults and tweaks to make it most relevant to Club Data ##
|
20 |
+
- read reports on WP and address all issues in release ##
|
21 |
+
- move all custom filters / hacks to filter system - controlled from q_club ( or functions.php for most theme based controls ) ##
|
22 |
+
*/
|
23 |
|
24 |
+
defined( 'ABSPATH' ) OR exit;
|
25 |
|
26 |
+
if ( ! class_exists( 'q_report' ) ) {
|
27 |
+
|
28 |
+
// instatiate plugin via WP plugins_loaded - init is too late for CPT ##
|
29 |
+
add_action( 'init', array ( 'q_report', 'get_instance' ), 1000000 );
|
30 |
+
|
31 |
+
class q_report {
|
32 |
+
|
33 |
+
// Refers to a single instance of this class. ##
|
34 |
+
private static $instance = null;
|
35 |
+
|
36 |
+
// Plugin Settings
|
37 |
+
const version = '2.0.1';
|
38 |
+
static $debug = true;
|
39 |
+
const text_domain = 'q-report'; // for translation ##
|
40 |
+
|
41 |
/* properties */
|
42 |
+
public static $q_report_exports = ''; // export settings ##
|
43 |
+
public static $usermeta_saved_fields = array();
|
44 |
+
public static $bp_fields_saved_fields = array();
|
45 |
+
public static $bp_fields_update_time_saved_fields = array();
|
46 |
+
public static $role = '';
|
47 |
+
public static $roles = '0';
|
48 |
+
public static $user_fields = '1';
|
49 |
+
public static $groups = '0';
|
50 |
+
public static $start_date = '';
|
51 |
+
public static $end_date = '';
|
52 |
+
public static $limit_offset = '';
|
53 |
+
public static $limit_total = '';
|
54 |
+
public static $updated_since_date = '';
|
55 |
+
public static $field_updated_since = '';
|
56 |
+
public static $format = '';
|
57 |
+
public static $bp_data_available = false;
|
58 |
+
public static $allowed_tags = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
// api ##
|
61 |
+
public static $api_admin_fields = false;
|
62 |
|
63 |
/**
|
64 |
+
* Creates or returns an instance of this class.
|
65 |
*
|
66 |
+
* @return Foo A single instance of this class.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
*/
|
68 |
+
public static function get_instance()
|
69 |
{
|
70 |
|
71 |
+
if ( null == self::$instance ) {
|
72 |
+
self::$instance = new self;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
+
return self::$instance;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
+
|
79 |
+
|
80 |
/**
|
81 |
+
* Instatiate Class
|
82 |
+
*
|
83 |
+
* @since 0.2
|
84 |
+
* @return void
|
85 |
*/
|
86 |
+
private function __construct()
|
87 |
{
|
88 |
+
|
89 |
+
// activation ##
|
90 |
+
register_activation_hook( __FILE__, array ( $this, 'register_activation_hook' ) );
|
91 |
|
92 |
+
// deactvation ##
|
93 |
+
register_deactivation_hook( __FILE__, array ( $this, 'register_deactivation_hook' ) );
|
|
|
|
|
94 |
|
95 |
+
// set text domain ##
|
96 |
+
add_action( 'init', array( $this, 'load_plugin_textdomain' ), 1 );
|
97 |
+
|
98 |
+
// load libraries ##
|
99 |
+
self::load_libraries();
|
|
|
|
|
|
|
100 |
|
101 |
}
|
102 |
|
103 |
|
104 |
+
// the form for sites have to be 1-column-layout
|
105 |
+
public function register_activation_hook() {
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
+
\add_option( 'q_report_configured' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
+
// flush rewrites ##
|
110 |
+
#global $wp_rewrite;
|
111 |
+
#$wp_rewrite->flush_rules();
|
112 |
|
113 |
}
|
114 |
|
115 |
|
116 |
+
public function register_deactivation_hook() {
|
117 |
|
118 |
+
\delete_option( 'q_report_configured' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
|
120 |
}
|
121 |
|
122 |
|
123 |
+
|
124 |
/**
|
125 |
+
* Load Text Domain for translations
|
126 |
+
*
|
127 |
+
* @since 1.7.0
|
128 |
+
*
|
|
|
129 |
*/
|
130 |
+
public function load_plugin_textdomain()
|
131 |
{
|
132 |
+
|
133 |
+
// set text-domain ##
|
134 |
+
$domain = self::text_domain;
|
135 |
+
|
136 |
+
// The "plugin_locale" filter is also used in load_plugin_textdomain()
|
137 |
+
$locale = apply_filters('plugin_locale', get_locale(), $domain);
|
138 |
|
139 |
+
// try from global WP location first ##
|
140 |
+
load_textdomain( $domain, WP_LANG_DIR.'/plugins/'.$domain.'-'.$locale.'.mo' );
|
141 |
+
|
142 |
+
// try from plugin last ##
|
143 |
+
load_plugin_textdomain( $domain, FALSE, plugin_dir_path( __FILE__ ).'library/languages/' );
|
144 |
+
|
|
|
145 |
}
|
146 |
+
|
147 |
+
|
148 |
+
|
149 |
/**
|
150 |
+
* Get Plugin URL
|
151 |
+
*
|
152 |
+
* @since 0.1
|
153 |
+
* @param string $path Path to plugin directory
|
154 |
+
* @return string Absoulte URL to plugin directory
|
155 |
*/
|
156 |
+
public static function get_plugin_url( $path = '' )
|
157 |
{
|
158 |
|
159 |
+
return plugins_url( $path, __FILE__ );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
}
|
162 |
+
|
163 |
+
|
164 |
/**
|
165 |
+
* Get Plugin Path
|
166 |
+
*
|
167 |
+
* @since 0.1
|
168 |
+
* @param string $path Path to plugin directory
|
169 |
+
* @return string Absoulte URL to plugin directory
|
170 |
*/
|
171 |
+
public static function get_plugin_path( $path = '' )
|
172 |
{
|
173 |
|
174 |
+
return plugin_dir_path( __FILE__ ).$path;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
}
|
177 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
|
179 |
/**
|
180 |
+
* Load Libraries
|
181 |
+
*
|
182 |
+
* @since 2.0
|
183 |
+
*/
|
184 |
+
private static function load_libraries()
|
|
|
|
|
185 |
{
|
186 |
|
187 |
+
// methods ##
|
188 |
+
require_once self::get_plugin_path( 'library/core/helper.php' );
|
189 |
+
require_once self::get_plugin_path( 'library/core/core.php' );
|
190 |
+
require_once self::get_plugin_path( 'library/core/user.php' );
|
191 |
+
require_once self::get_plugin_path( 'library/core/buddypress.php' );
|
192 |
+
require_once self::get_plugin_path( 'library/core/xml.php' );
|
193 |
+
require_once self::get_plugin_path( 'library/core/export.php' );
|
194 |
+
require_once self::get_plugin_path( 'library/core/filters.php' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
|
196 |
+
// api ##
|
197 |
+
require_once self::get_plugin_path( 'library/api/admin.php' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
+
// backend ##
|
200 |
+
require_once self::get_plugin_path( 'library/admin/admin.php' );
|
201 |
+
|
202 |
}
|
203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
}
|
205 |
|
206 |
+
}
|
|
library/admin/admin.php
ADDED
@@ -0,0 +1,838 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\admin;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
use q\report\core\user as user;
|
8 |
+
use q\report\core\buddypress as buddypress;
|
9 |
+
use q\report\api\admin as api_admin;
|
10 |
+
|
11 |
+
// load it up ##
|
12 |
+
\q\report\admin\admin::run();
|
13 |
+
|
14 |
+
class admin extends \q_report {
|
15 |
+
|
16 |
+
public static function run()
|
17 |
+
{
|
18 |
+
|
19 |
+
#global $pagenow;
|
20 |
+
|
21 |
+
if ( \is_admin() ) {
|
22 |
+
|
23 |
+
// add export menu inside admin ##
|
24 |
+
\add_action( 'admin_menu', array( get_class(), 'add_menu' ) );
|
25 |
+
|
26 |
+
// UI style and functionality ##
|
27 |
+
\add_action( 'admin_enqueue_scripts', array( get_class(), 'admin_enqueue_scripts' ), 1 );
|
28 |
+
\add_action( 'admin_footer', array( get_class(), 'jquery' ), 100000 );
|
29 |
+
\add_action( 'admin_footer', array( get_class(), 'css' ), 100000 );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Add administration menus
|
39 |
+
*
|
40 |
+
* @since 0.1
|
41 |
+
**/
|
42 |
+
public static function add_menu()
|
43 |
+
{
|
44 |
+
|
45 |
+
add_users_page (
|
46 |
+
__( 'Export User Data', 'q-report' ),
|
47 |
+
__( 'Export User Data', 'q-report' ),
|
48 |
+
\apply_filters( 'q/report/admin_capability', 'list_users' ),
|
49 |
+
'q-report',
|
50 |
+
array(
|
51 |
+
get_class(),
|
52 |
+
'admin_page'
|
53 |
+
)
|
54 |
+
);
|
55 |
+
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Content of the admin page
|
61 |
+
*
|
62 |
+
* @since 0.1
|
63 |
+
*/
|
64 |
+
public static function admin_page()
|
65 |
+
{
|
66 |
+
|
67 |
+
// quick security check ##
|
68 |
+
if ( ! \current_user_can( \apply_filters( 'q/report/admin_capability', 'list_users' ) ) ) {
|
69 |
+
|
70 |
+
\wp_die( __( 'You do not have sufficient permissions to access this page.', 'q-report' ) );
|
71 |
+
|
72 |
+
}
|
73 |
+
|
74 |
+
// Save settings button was pressed ##
|
75 |
+
if (
|
76 |
+
isset( $_POST['save_export'] )
|
77 |
+
&& \check_admin_referer( 'q-report-admin-page', '_wpnonce-q-report-admin-page' )
|
78 |
+
) {
|
79 |
+
|
80 |
+
// start with an empty variable ##
|
81 |
+
$save_export = "";
|
82 |
+
|
83 |
+
if ( ! empty( $_POST['save_new_export_name'] ) ) {
|
84 |
+
|
85 |
+
// assign value ##
|
86 |
+
$save_export = $_POST['save_new_export_name'];
|
87 |
+
|
88 |
+
} elseif ( ! empty( $_POST['export_name'] ) ) {
|
89 |
+
|
90 |
+
$save_export = $_POST['export_name'];
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
// clean up $save_export ##
|
95 |
+
$save_export = \sanitize_text_field( $save_export );
|
96 |
+
|
97 |
+
// Build array of $options to save and save them ##
|
98 |
+
if ( isset( $save_export ) ) {
|
99 |
+
|
100 |
+
// prepare all array values ##
|
101 |
+
$usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '' ;
|
102 |
+
$bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '' ;
|
103 |
+
$bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '' ;
|
104 |
+
$format = isset( $_POST['format'] ) ? $_POST['format'] : '' ;
|
105 |
+
$role = isset( $_POST['role'] ) ? $_POST['role'] : '' ;
|
106 |
+
$roles = isset( $_POST['roles'] ) ? $_POST['roles'] : '0' ;
|
107 |
+
$user_fields = isset( $_POST['user_fields'] ) ? $_POST['user_fields'] : '0' ;
|
108 |
+
$groups = isset( $_POST['groups'] ) ? $_POST['groups'] : '0' ;
|
109 |
+
$start_date = isset( $_POST['start_date'] ) ? $_POST['start_date'] : '' ;
|
110 |
+
$end_date = isset( $_POST['end_date'] ) ? $_POST['end_date'] : '' ;
|
111 |
+
$limit_offset = isset( $_POST['limit_offset'] ) ? $_POST['limit_offset'] : '' ;
|
112 |
+
$limit_total = isset( $_POST['limit_total'] ) ? $_POST['limit_total'] : '' ;
|
113 |
+
$updated_since_date = isset ( $_POST['updated_since_date'] ) ? $_POST['updated_since_date'] : '' ;
|
114 |
+
$field_updated_since = isset ( $_POST['bp_field_updated_since'] ) ? $_POST['bp_field_updated_since'] : '';
|
115 |
+
|
116 |
+
// assign all values to an array ##
|
117 |
+
$save_array = array (
|
118 |
+
'usermeta_saved_fields' => $usermeta,
|
119 |
+
'bp_fields_saved_fields' => $bp_fields,
|
120 |
+
'bp_fields_update_time_saved_fields' => $bp_fields_update,
|
121 |
+
'role' => $role,
|
122 |
+
'roles' => $roles,
|
123 |
+
'user_fields' => $user_fields,
|
124 |
+
'groups' => $groups,
|
125 |
+
'start_date' => $start_date,
|
126 |
+
'end_date' => $end_date,
|
127 |
+
'limit_offset' => $limit_offset,
|
128 |
+
'limit_total' => $limit_total,
|
129 |
+
'updated_since_date' => $updated_since_date,
|
130 |
+
'field_updated_since' => $field_updated_since,
|
131 |
+
'format' => $format
|
132 |
+
);
|
133 |
+
|
134 |
+
// store the options, for next load ##
|
135 |
+
user::set_user_options( $save_export, $save_array );
|
136 |
+
|
137 |
+
// Display the settings the user just saved instead of blanking the form ##
|
138 |
+
$_POST['load_export'] = 'Load Settings';
|
139 |
+
$_POST['export_name'] = $save_export;
|
140 |
+
|
141 |
+
}
|
142 |
+
|
143 |
+
}
|
144 |
+
|
145 |
+
// Load settings button was pressed ( or option saved and $_POST variables hijacked )##
|
146 |
+
if (
|
147 |
+
isset( $_POST['load_export'] )
|
148 |
+
&& isset( $_POST['export_name'] )
|
149 |
+
&& \check_admin_referer( 'q-report-admin-page', '_wpnonce-q-report-admin-page' )
|
150 |
+
) {
|
151 |
+
|
152 |
+
user::get_user_options_by_export( \sanitize_text_field( $_POST['export_name'] ) );
|
153 |
+
|
154 |
+
}
|
155 |
+
|
156 |
+
// Delete settings button was pressed ##
|
157 |
+
if (
|
158 |
+
isset( $_POST['delete_export'] )
|
159 |
+
&& isset( $_POST['export_name'] )
|
160 |
+
&& \check_admin_referer( 'q-report-admin-page', '_wpnonce-q-report-admin-page' )
|
161 |
+
) {
|
162 |
+
|
163 |
+
user::delete_user_options( \sanitize_text_field( $_POST['export_name'] ) );
|
164 |
+
|
165 |
+
}
|
166 |
+
|
167 |
+
?>
|
168 |
+
<div class="wrap">
|
169 |
+
<h2><?php \_e( 'Export User Data', 'q-report' ); ?></h2>
|
170 |
+
<?php
|
171 |
+
|
172 |
+
// nothing happening? ##
|
173 |
+
if ( isset( $_GET['error'] ) ) {
|
174 |
+
echo '<div class="updated"><p><strong>' . \__( 'No users found.', 'q-report' ) . '</strong></p></div>';
|
175 |
+
}
|
176 |
+
|
177 |
+
?>
|
178 |
+
<form method="post" action="" enctype="multipart/form-data">
|
179 |
+
<?php \wp_nonce_field( 'q-report-admin-page', '_wpnonce-q-report-admin-page' ); ?>
|
180 |
+
<table class="form-table">
|
181 |
+
<?php
|
182 |
+
|
183 |
+
// allow admin to select user meta fields to export ##
|
184 |
+
global $wpdb;
|
185 |
+
|
186 |
+
// filterable SQL ##
|
187 |
+
$meta_keys = \apply_filters(
|
188 |
+
'q/report/admin/sql',
|
189 |
+
$wpdb->get_results( "SELECT distinct(meta_key) FROM $wpdb->usermeta" )
|
190 |
+
);
|
191 |
+
|
192 |
+
// filterable sort ##
|
193 |
+
\apply_filters(
|
194 |
+
'q/report/admin/sort',
|
195 |
+
asort( $meta_keys )
|
196 |
+
);
|
197 |
+
|
198 |
+
// get meta_key value from object ##
|
199 |
+
$meta_keys = \wp_list_pluck( $meta_keys, 'meta_key' );
|
200 |
+
|
201 |
+
// allow array to be filtered ##
|
202 |
+
$meta_keys_common = \apply_filters( 'q/report/admin/meta_keys_common', [] );
|
203 |
+
|
204 |
+
// test array ##
|
205 |
+
#helper::log( $meta_keys );
|
206 |
+
#helper::log( $meta_keys_common );
|
207 |
+
|
208 |
+
// check if we got anything ? ##
|
209 |
+
if ( $meta_keys ) {
|
210 |
+
|
211 |
+
?>
|
212 |
+
<tr valign="top">
|
213 |
+
<th scope="row">
|
214 |
+
<label for="q_report_usermeta"><?php \_e( 'User Meta Fields', 'q-report' ); ?></label>
|
215 |
+
<p class="filter" style="margin: 10px 0 0;">
|
216 |
+
<?php \_e('Filter', 'q-report'); ?>: <a href="#" class="usermeta-all"><?php \_e('All', 'q-report'); ?></a> | <a href="#" class="usermeta-common"><?php \_e('Common', 'q-report'); ?></a>
|
217 |
+
</p>
|
218 |
+
<p class="filter" style="margin: 10px 0 0;">
|
219 |
+
<?php \_e('Select', 'q-report'); ?>: <a href="#" class="select-all"><?php \_e('All', 'q-report'); ?></a> | <a href="#" class="select-none"><?php \_e('None', 'q-report'); ?></a>
|
220 |
+
</p>
|
221 |
+
</th>
|
222 |
+
<td>
|
223 |
+
<select multiple="multiple" id="usermeta" name="usermeta[]">
|
224 |
+
<?php
|
225 |
+
|
226 |
+
foreach ( $meta_keys as $key ) {
|
227 |
+
|
228 |
+
// filter key displayed ##
|
229 |
+
$display_key = \apply_filters( 'q/report/admin/display_key', $key );
|
230 |
+
|
231 |
+
// class ##
|
232 |
+
$usermeta_class = 'normal';
|
233 |
+
|
234 |
+
foreach ( $meta_keys_common as $drop ) {
|
235 |
+
|
236 |
+
#helper::log( 'Checking: '.$drop );
|
237 |
+
|
238 |
+
if ( strpos( $key, $drop ) !== false ) {
|
239 |
+
|
240 |
+
#helper::log( 'Checking: '.$key );
|
241 |
+
|
242 |
+
// https://wordpress.org/support/topic/bugfix-numbers-in-export-headers?replies=1
|
243 |
+
// removed $key = assignment, as not required ##
|
244 |
+
if ( ( array_search( $key, $meta_keys ) ) !== false ) {
|
245 |
+
|
246 |
+
#helper::log( 'Found: '.$key );
|
247 |
+
|
248 |
+
$usermeta_class = 'common';
|
249 |
+
|
250 |
+
}
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
}
|
255 |
+
|
256 |
+
// print key ##
|
257 |
+
echo "<option value='".\esc_attr( $key )."' title='".\esc_attr( $key )."' class='".$usermeta_class."'>$display_key</option>";
|
258 |
+
|
259 |
+
}
|
260 |
+
?>
|
261 |
+
</select>
|
262 |
+
<p class="description"><?php
|
263 |
+
printf(
|
264 |
+
\__( 'Select the user meta keys to export, use the filters to simplify the list.', 'q-report' )
|
265 |
+
);
|
266 |
+
?></p>
|
267 |
+
</td>
|
268 |
+
</tr>
|
269 |
+
<?php
|
270 |
+
|
271 |
+
} // meta_keys found ##
|
272 |
+
|
273 |
+
?>
|
274 |
+
<?php
|
275 |
+
|
276 |
+
// buddypress x profile data ##
|
277 |
+
if ( $bp_fields = buddypress::get_fields() ) {
|
278 |
+
|
279 |
+
?>
|
280 |
+
<tr valign="top">
|
281 |
+
<th scope="row">
|
282 |
+
<label for="q_report_xprofile"><?php \_e( 'BP xProfile Fields', 'q-report' ); ?></label>
|
283 |
+
<p class="filter" style="margin: 10px 0 0;">
|
284 |
+
<?php \_e('Select', 'q-report'); ?>: <a href="#" class="select-all"><?php \_e('All', 'q-report'); ?></a> | <a href="#" class="select-none"><?php \_e('None', 'q-report'); ?></a>
|
285 |
+
</p>
|
286 |
+
</th>
|
287 |
+
<td>
|
288 |
+
<select multiple="multiple" id="bp_fields" name="bp_fields[]">
|
289 |
+
<?php
|
290 |
+
|
291 |
+
foreach ( $bp_fields as $key ) {
|
292 |
+
|
293 |
+
// print key ##
|
294 |
+
echo "<option value='".\esc_attr( $key )."' title='".\esc_attr( $key )."'>$key</option>";
|
295 |
+
|
296 |
+
}
|
297 |
+
|
298 |
+
?>
|
299 |
+
</select>
|
300 |
+
<p class="description"><?php
|
301 |
+
printf(
|
302 |
+
\__( 'Select the BuddyPress XProfile keys to export', 'q-report' )
|
303 |
+
);
|
304 |
+
?></p>
|
305 |
+
</td>
|
306 |
+
</tr>
|
307 |
+
<?php
|
308 |
+
|
309 |
+
// allow export of update times ##
|
310 |
+
|
311 |
+
?>
|
312 |
+
<tr valign="top" class="toggleable">
|
313 |
+
<th scope="row">
|
314 |
+
<label for="q_report_xprofile"><?php \_e( 'BP xProfile Fields Update Time', 'q-report' ); ?></label>
|
315 |
+
<p class="filter" style="margin: 10px 0 0;">
|
316 |
+
<?php \_e('Select', 'q-report'); ?>: <a href="#" class="select-all"><?php \_e('All', 'q-report'); ?></a> | <a href="#" class="select-none"><?php _e('None', 'q-report'); ?></a>
|
317 |
+
</p>
|
318 |
+
</th>
|
319 |
+
<td>
|
320 |
+
<select multiple="multiple" id="bp_fields_update_time" name="bp_fields_update_time[]">
|
321 |
+
<?php
|
322 |
+
|
323 |
+
foreach ( $bp_fields as $key ) {
|
324 |
+
|
325 |
+
echo "<option value='".\esc_attr( $key )."' title='".\esc_attr( $key )."'>$key</option>";
|
326 |
+
|
327 |
+
}
|
328 |
+
|
329 |
+
?>
|
330 |
+
</select>
|
331 |
+
<p class="description"><?php
|
332 |
+
printf(
|
333 |
+
\__( 'Select the BuddyPress XProfile keys updated dates to export', 'q-report' )
|
334 |
+
);
|
335 |
+
?></p>
|
336 |
+
</td>
|
337 |
+
</tr>
|
338 |
+
|
339 |
+
<tr valign="top" class="toggleable">
|
340 |
+
<th scope="row"><label for="groups"><?php \_e( 'BP User Groups', 'q-report' ); ?></label></th>
|
341 |
+
<td>
|
342 |
+
<input id='groups' type='checkbox' name='groups' value='1' <?php \checked( isset ( self::$groups ) ? intval ( self::$groups ) : '', 1 ); ?> />
|
343 |
+
<p class="description"><?php
|
344 |
+
printf(
|
345 |
+
\__( 'Include BuddyPress Group Data. <a href="%s" target="_blank">%s</a>', 'q-report' )
|
346 |
+
, \esc_html('https://codex.buddypress.org/buddypress-components-and-features/groups/')
|
347 |
+
, 'Codex'
|
348 |
+
);
|
349 |
+
?></p>
|
350 |
+
</td>
|
351 |
+
</tr>
|
352 |
+
<?php
|
353 |
+
|
354 |
+
} // BP installed and active ##
|
355 |
+
|
356 |
+
?>
|
357 |
+
<tr valign="top" class="toggleable">
|
358 |
+
<th scope="row"><label for="user_fields"><?php \_e( 'Standard User Fields', 'q-report' ); ?></label></th>
|
359 |
+
<td>
|
360 |
+
<input id='user_fields' type='checkbox' name='user_fields' value='1' <?php \checked( isset ( self::$user_fields ) ? intval ( self::$user_fields ) : '', 1 ); ?> />
|
361 |
+
<p class="description"><?php
|
362 |
+
|
363 |
+
#self::log( 'user_fields: '.self::$user_fields );
|
364 |
+
#echo 'user_fields: '. self::$user_fields;
|
365 |
+
|
366 |
+
printf(
|
367 |
+
\__( 'Include Standard user profile fields, such as user_login. <a href="%s" target="_blank">%s</a>', 'q-report' )
|
368 |
+
, \esc_html('https://codex.wordpress.org/Database_Description#Table:_wp_users')
|
369 |
+
, 'Codex'
|
370 |
+
);
|
371 |
+
|
372 |
+
?></p>
|
373 |
+
</td>
|
374 |
+
</tr>
|
375 |
+
|
376 |
+
<tr valign="top" class="toggleable">
|
377 |
+
<th scope="row"><label for="q_report_users_role"><?php \_e( 'Role', 'q-report' ); ?></label></th>
|
378 |
+
<td>
|
379 |
+
<select name="role" id="q_report_users_role">
|
380 |
+
<?php
|
381 |
+
|
382 |
+
echo '<option value="">' . \__( 'All Roles', 'q-report' ) . '</option>';
|
383 |
+
|
384 |
+
global $wp_roles;
|
385 |
+
|
386 |
+
foreach ( $wp_roles->role_names as $role => $name ) {
|
387 |
+
|
388 |
+
if ( isset ( self::$role ) && ( self::$role == $role ) ) {
|
389 |
+
|
390 |
+
echo "\n\t<option selected value='" . \esc_attr( $role ) . "'>$name</option>";
|
391 |
+
|
392 |
+
} else {
|
393 |
+
|
394 |
+
echo "\n\t<option value='" . \esc_attr( $role ) . "'>$name</option>";
|
395 |
+
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
|
400 |
+
?>
|
401 |
+
</select>
|
402 |
+
<p class="description"><?php
|
403 |
+
printf(
|
404 |
+
\__( 'Filter the exported users by a WordPress Role. <a href="%s" target="_blank">%s</a>', 'q-report' )
|
405 |
+
, \esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
|
406 |
+
, 'Codex'
|
407 |
+
);
|
408 |
+
?></p>
|
409 |
+
</td>
|
410 |
+
</tr>
|
411 |
+
|
412 |
+
<tr valign="top" class="toggleable">
|
413 |
+
<th scope="row"><label for="roles"><?php \_e( 'User Roles', 'q-report' ); ?></label></th>
|
414 |
+
<td>
|
415 |
+
<input id='roles' type='checkbox' name='roles' value='1' <?php \checked( isset ( self::$roles ) ? intval ( self::$roles ) : '', 1 ); ?> />
|
416 |
+
<p class="description"><?php
|
417 |
+
printf(
|
418 |
+
\__( 'Include all of the users <a href="%s" target="_blank">%s</a>', 'q-report' )
|
419 |
+
, \esc_html('http://codex.wordpress.org/Roles_and_Capabilities')
|
420 |
+
, 'Roles'
|
421 |
+
);
|
422 |
+
?></p>
|
423 |
+
</td>
|
424 |
+
</tr>
|
425 |
+
|
426 |
+
<tr valign="top" class="toggleable">
|
427 |
+
<th scope="row"><label><?php \_e( 'Registered', 'q-report' ); ?></label></th>
|
428 |
+
<td>
|
429 |
+
<input type="text" id="q_report_users_start_date" name="start_date" value="<?php echo self::$start_date; ?>" class="start-datepicker" />
|
430 |
+
<input type="text" id="q_report_users_end_date" name="end_date" value="<?php echo self::$end_date; ?>" class="end-datepicker" />
|
431 |
+
<p class="description"><?php
|
432 |
+
printf(
|
433 |
+
\__( 'Pick a start and end user registration date to limit the results.', 'q-report' )
|
434 |
+
);
|
435 |
+
?></p>
|
436 |
+
</td>
|
437 |
+
</tr>
|
438 |
+
|
439 |
+
<tr valign="top" class="toggleable">
|
440 |
+
<th scope="row"><label><?php \_e( 'Limit Range', 'q-report' ); ?></label></th>
|
441 |
+
<td>
|
442 |
+
<input name="limit_offset" type="text" id="q_report_users_limit_offset" value="<?php echo( self::$limit_offset ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Offset', 'q-report' ); ?>">
|
443 |
+
<input name="limit_total" type="text" id="q_report_users_limit_total" value="<?php echo ( self::$limit_total ); ?>" class="regular-text code numeric" style="width: 136px;" placeholder="<?php _e( 'Total', 'q-report' ); ?>">
|
444 |
+
<p class="description"><?php
|
445 |
+
printf(
|
446 |
+
\__( 'Enter an offset start number and a total number of users to export. <a href="%s" target="_blank">%s</a>', 'q-report' )
|
447 |
+
, \esc_html('http://codex.wordpress.org/Function_Reference/get_users#Parameters')
|
448 |
+
, 'Codex'
|
449 |
+
);
|
450 |
+
?></p>
|
451 |
+
</td>
|
452 |
+
</tr>
|
453 |
+
<?php
|
454 |
+
|
455 |
+
// buddypress x profile data ##
|
456 |
+
if ( $bp_fields = buddypress::get_fields() ) {
|
457 |
+
|
458 |
+
?>
|
459 |
+
<tr valign="top" class="toggleable">
|
460 |
+
<th scope="row"><label><?php \_e( 'Updated Since', 'q-report' ); ?></label></th>
|
461 |
+
<td>
|
462 |
+
<input type="text" id="q_report_updated_since_date" name="updated_since_date" value="<?php echo self::$updated_since_date; ?>" class="updated-datepicker" />
|
463 |
+
<select id="bp_field_updated_since" name="bp_field_updated_since">
|
464 |
+
<?php
|
465 |
+
|
466 |
+
foreach ( $bp_fields as $key ) {
|
467 |
+
|
468 |
+
if ( self::$field_updated_since == $key ) {
|
469 |
+
|
470 |
+
echo "<option value='".\esc_attr( $key )."' title='".\esc_attr( $key )."' selected>$key</option>";
|
471 |
+
|
472 |
+
} else {
|
473 |
+
|
474 |
+
echo "<option value='".\esc_attr( $key )."' title='".\esc_attr( $key )."'>$key</option>";
|
475 |
+
|
476 |
+
}
|
477 |
+
|
478 |
+
}
|
479 |
+
|
480 |
+
?>
|
481 |
+
</select>
|
482 |
+
|
483 |
+
<p class="description"><?php
|
484 |
+
printf(
|
485 |
+
\__( 'Limit the results to users who have updated this extended profile field after this date.', 'q-report' )
|
486 |
+
);
|
487 |
+
?></p>
|
488 |
+
</td>
|
489 |
+
</tr>
|
490 |
+
<?php
|
491 |
+
|
492 |
+
} // bp date ##
|
493 |
+
|
494 |
+
// pull in extra export options from api ##
|
495 |
+
if ( $api_fields = \apply_filters( 'q/report/api/admin/fields', [] ) ) {
|
496 |
+
|
497 |
+
foreach( $api_fields as $field ) {
|
498 |
+
|
499 |
+
api_admin::render( $field );
|
500 |
+
|
501 |
+
}
|
502 |
+
|
503 |
+
}
|
504 |
+
|
505 |
+
?>
|
506 |
+
<tr valign="top">
|
507 |
+
<th scope="row"><label for="q_report_users_format"><?php \_e( 'Format', 'q-report' ); ?></label></th>
|
508 |
+
<td>
|
509 |
+
<select name="format" id="q_report_users_format">
|
510 |
+
<?php
|
511 |
+
if ( isset ( self::$format ) && ( self::$format == 'excel' ) ) {
|
512 |
+
|
513 |
+
echo '<option selected value="excel">' . __( 'Excel', 'q-report' ) . '</option>';
|
514 |
+
|
515 |
+
} else {
|
516 |
+
|
517 |
+
echo '<option value="excel">' . __( 'Excel', 'q-report' ) . '</option>';
|
518 |
+
|
519 |
+
}
|
520 |
+
|
521 |
+
if ( isset ( self::$format ) && ( self::$format == 'csv' ) ) {
|
522 |
+
|
523 |
+
echo '<option selected value="csv">' . __( 'CSV', 'q-report' ) . '</option>';
|
524 |
+
|
525 |
+
} else {
|
526 |
+
|
527 |
+
echo '<option value="csv">' . __( 'CSV', 'q-report' ) . '</option>';
|
528 |
+
|
529 |
+
}
|
530 |
+
?>
|
531 |
+
</select>
|
532 |
+
<p class="description"><?php
|
533 |
+
printf(
|
534 |
+
\__( 'Select the format for the export file.', 'q-report' )
|
535 |
+
);
|
536 |
+
?></p>
|
537 |
+
</td>
|
538 |
+
</tr>
|
539 |
+
|
540 |
+
<tr valign="top" class="remember">
|
541 |
+
<th scope="row"><label for="q_report_save_options"><?php \_e( 'Stored Options', 'q-report' ); ?></label></th>
|
542 |
+
<td>
|
543 |
+
|
544 |
+
<div class="row">
|
545 |
+
<input type="text" class="regular-text" name="save_new_export_name" id="q_report_save_options_new_export" placeholder="<?php \_e( 'Export Name', 'q-report' ); ?>" value="<?php echo isset( $_POST['export_name'] ) ? \sanitize_text_field( $_POST['export_name'] ) : '' ; ?>">
|
546 |
+
<input type="submit" id="save_export" class="button-primary" name="save_export" value="<?php \_e( 'Save', 'q-report' ); ?>" />
|
547 |
+
</div>
|
548 |
+
<?php
|
549 |
+
|
550 |
+
// check if the user has any saved exports ##
|
551 |
+
if ( user::get_user_options() ) {
|
552 |
+
|
553 |
+
?>
|
554 |
+
<div class="row">
|
555 |
+
<select name="export_name" id="q_report_save_options" class="regular-text">
|
556 |
+
<?php
|
557 |
+
|
558 |
+
// loop over each saved export ##
|
559 |
+
foreach( user::get_user_options() as $export ) {
|
560 |
+
|
561 |
+
// select Loaded export name, if selected ##
|
562 |
+
if (
|
563 |
+
isset( $_POST['load_export'] )
|
564 |
+
&& isset( $_POST['export_name'] )
|
565 |
+
&& ( $_POST['export_name'] == $export )
|
566 |
+
) {
|
567 |
+
|
568 |
+
echo "<option selected value='$export'>".$export."</option>";
|
569 |
+
|
570 |
+
// just list previous export name ##
|
571 |
+
} else {
|
572 |
+
|
573 |
+
echo "<option value='$export'>".$export."</option>";
|
574 |
+
|
575 |
+
}
|
576 |
+
|
577 |
+
}
|
578 |
+
|
579 |
+
?>
|
580 |
+
</select>
|
581 |
+
|
582 |
+
<input type="submit" id="load_export" class="button-primary" name="load_export" value="<?php _e( 'Load', 'q-report' ); ?>" />
|
583 |
+
<input type="submit" id="delete_export" class="button-primary" name="delete_export" value="<?php _e( 'Delete', 'q-report' ); ?>" />
|
584 |
+
<?php
|
585 |
+
|
586 |
+
}
|
587 |
+
|
588 |
+
?>
|
589 |
+
</div>
|
590 |
+
<p class="description"><?php \_e( 'Save, load or delete your stored export options.', 'q-report' ); ?></p>
|
591 |
+
|
592 |
+
</td>
|
593 |
+
</tr>
|
594 |
+
|
595 |
+
<tr valign="top">
|
596 |
+
<th scope="row">
|
597 |
+
<label for="q_report_xprofile"><?php \_e( 'Advanced Options', 'q-report' ); ?></label>
|
598 |
+
</th>
|
599 |
+
<td>
|
600 |
+
<div class="toggle">
|
601 |
+
<a href="#"><?php \_e( 'Show', 'q-report' ); ?></a>
|
602 |
+
</div>
|
603 |
+
</td>
|
604 |
+
</tr>
|
605 |
+
|
606 |
+
</table>
|
607 |
+
<p class="submit">
|
608 |
+
<input type="hidden" name="_wp_http_referer" value="<?php echo \esc_url( $_SERVER['REQUEST_URI'] ); ?>" />
|
609 |
+
<input type="submit" class="button-primary" value="<?php \_e( 'Run Export', 'q-report' ); ?>" />
|
610 |
+
</p>
|
611 |
+
</form>
|
612 |
+
</div>
|
613 |
+
|
614 |
+
<?php
|
615 |
+
}
|
616 |
+
|
617 |
+
|
618 |
+
|
619 |
+
/**
|
620 |
+
* style and interaction
|
621 |
+
*/
|
622 |
+
public static function admin_enqueue_scripts( $hook )
|
623 |
+
{
|
624 |
+
|
625 |
+
// load the scripts on only the plugin admin page ##
|
626 |
+
if (
|
627 |
+
! isset( $_GET['page'] )
|
628 |
+
|| $_GET['page'] != 'q-report'
|
629 |
+
|
630 |
+
) {
|
631 |
+
|
632 |
+
return false;
|
633 |
+
|
634 |
+
}
|
635 |
+
|
636 |
+
\wp_register_style( 'q-report-css', \plugins_url( 'css/q-report.css' ,__FILE__ ), '', self::version );
|
637 |
+
\wp_enqueue_style( 'q-report-css' );
|
638 |
+
\wp_enqueue_script( 'q_report_multi_select_js', \plugins_url( 'javascript/jquery.multi-select.js', __FILE__ ), array('jquery'), '0.9.8', false );
|
639 |
+
|
640 |
+
// add script ##
|
641 |
+
\wp_enqueue_script('jquery-ui-datepicker');
|
642 |
+
|
643 |
+
// add style ##
|
644 |
+
\wp_enqueue_style( 'jquery-ui-datepicker' );
|
645 |
+
\wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
|
646 |
+
|
647 |
+
}
|
648 |
+
|
649 |
+
|
650 |
+
|
651 |
+
|
652 |
+
/**
|
653 |
+
* Inline jQuery
|
654 |
+
* @since 0.8.2
|
655 |
+
*/
|
656 |
+
public static function jquery()
|
657 |
+
{
|
658 |
+
|
659 |
+
// load the scripts on only the plugin admin page
|
660 |
+
if (
|
661 |
+
! isset( $_GET['page'] )
|
662 |
+
|| $_GET['page'] != 'q-report'
|
663 |
+
) {
|
664 |
+
|
665 |
+
return false;
|
666 |
+
|
667 |
+
}
|
668 |
+
|
669 |
+
?>
|
670 |
+
<script>
|
671 |
+
|
672 |
+
// lazy load in some jQuery validation ##
|
673 |
+
jQuery(document).ready(function($) {
|
674 |
+
|
675 |
+
// build super multiselect ##
|
676 |
+
jQuery('#usermeta, #bp_fields, #bp_fields_update_time').multiSelect();
|
677 |
+
|
678 |
+
// Select any fields from saved settings ##
|
679 |
+
jQuery('#usermeta').multiSelect('select',([<?php echo( core::quote_array( self::$usermeta_saved_fields ) ); ?>]));
|
680 |
+
jQuery('#bp_fields').multiSelect('select',([<?php echo( core::quote_array( self::$bp_fields_saved_fields ) ); ?>]));
|
681 |
+
jQuery('#bp_fields_update_time').multiSelect('select',([<?php echo( core::quote_array( self::$bp_fields_update_time_saved_fields ) ); ?>]));
|
682 |
+
|
683 |
+
// show only common ##
|
684 |
+
jQuery('.usermeta-common').click(function(e){
|
685 |
+
// console.log( 'Common..' );
|
686 |
+
e.preventDefault();
|
687 |
+
jQuery('#ms-usermeta .ms-selectable li.normal').hide();
|
688 |
+
});
|
689 |
+
|
690 |
+
// show all ##
|
691 |
+
jQuery('.usermeta-all').click(function(e){
|
692 |
+
e.preventDefault();
|
693 |
+
jQuery('#ms-usermeta .ms-selectable li').show();
|
694 |
+
});
|
695 |
+
|
696 |
+
// select all ##
|
697 |
+
jQuery('.select-all').click(function(e){
|
698 |
+
e.preventDefault();
|
699 |
+
jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'select_all' );
|
700 |
+
});
|
701 |
+
|
702 |
+
// select none ##
|
703 |
+
jQuery('.select-none').click(function(e){
|
704 |
+
e.preventDefault();
|
705 |
+
jQuery( jQuery(this).parent().parent().parent().find( 'select' ) ).multiSelect( 'deselect_all' );
|
706 |
+
});
|
707 |
+
|
708 |
+
|
709 |
+
// validate number inputs ##
|
710 |
+
$("input.numeric").blur(function() {
|
711 |
+
|
712 |
+
//console.log("you entered "+ $(this).val());
|
713 |
+
|
714 |
+
if ( $(this).val() && ! $.isNumeric( $(this).val() ) ) {
|
715 |
+
|
716 |
+
//console.log("this IS NOT a number");
|
717 |
+
$(this).css({ 'background': 'red', 'color': 'white' }); // highlight error ##
|
718 |
+
$("p.submit .button-primary").attr('disabled','disabled'); // disable submit ##
|
719 |
+
|
720 |
+
} else {
|
721 |
+
|
722 |
+
$(this).css({ 'background': 'white', 'color': '#333' }); // remove error highlighting ##
|
723 |
+
$("p.submit .button-primary").removeAttr('disabled'); // enable submit ##
|
724 |
+
|
725 |
+
}
|
726 |
+
|
727 |
+
});
|
728 |
+
|
729 |
+
// toggle advanced options ##
|
730 |
+
jQuery(".toggle a").click( function(e) {
|
731 |
+
e.preventDefault();
|
732 |
+
$toggleable = jQuery("tr.toggleable");
|
733 |
+
$toggleable.toggle();
|
734 |
+
if ( $toggleable.is(":visible") ) {
|
735 |
+
jQuery(this).text("<?php _e( 'Hide', 'q-report' ); ?>");
|
736 |
+
} else {
|
737 |
+
jQuery(this).text("<?php _e( 'Show', 'q-report' ); ?>");
|
738 |
+
}
|
739 |
+
});
|
740 |
+
|
741 |
+
// validate save button ##
|
742 |
+
jQuery("#save_export").click( function(e) {
|
743 |
+
|
744 |
+
// grab the value of the input ##
|
745 |
+
var q_report_save_options_new_export = jQuery('#q_report_save_options_new_export').val();
|
746 |
+
|
747 |
+
if ( ! q_report_save_options_new_export || q_report_save_options_new_export == '' ) {
|
748 |
+
|
749 |
+
e.preventDefault(); // stop things here ##
|
750 |
+
jQuery('#q_report_save_options_new_export').addClass("error");
|
751 |
+
|
752 |
+
}
|
753 |
+
|
754 |
+
});
|
755 |
+
|
756 |
+
// remove validation on focus ##
|
757 |
+
jQuery("body").on( 'focus', '#q_report_save_options_new_export', function(e) {
|
758 |
+
|
759 |
+
jQuery(this).removeClass("error");
|
760 |
+
|
761 |
+
});
|
762 |
+
|
763 |
+
<?php
|
764 |
+
|
765 |
+
// method returns an object with "first" & "last" keys ##
|
766 |
+
$dates = core::get_user_registered_dates();
|
767 |
+
|
768 |
+
// get date format from WP settings #
|
769 |
+
$date_format = 'yy-mm-dd' ; // get_option('date_format') ? get_option('date_format') : 'yy-mm-dd' ;
|
770 |
+
$start_of_week = \get_option('start_of_week') ? \get_option('start_of_week') : 'yy-mm-dd' ;
|
771 |
+
#self::log( 'Date format: '.$date_format );
|
772 |
+
|
773 |
+
?>
|
774 |
+
|
775 |
+
// start date picker ##
|
776 |
+
jQuery('.start-datepicker').datepicker( {
|
777 |
+
dateFormat : '<?php echo $date_format; ?>',
|
778 |
+
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
779 |
+
maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
|
780 |
+
firstDay : '<?php echo $start_of_week; ?>'
|
781 |
+
} );
|
782 |
+
|
783 |
+
// end date picker ##
|
784 |
+
jQuery('.end-datepicker').datepicker( {
|
785 |
+
dateFormat : '<?php echo $date_format; ?>',
|
786 |
+
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
787 |
+
maxDate : '<?php echo substr( $dates["0"]->last, 0, 10 ); ?>',
|
788 |
+
firstDay : '<?php echo $start_of_week; ?>'
|
789 |
+
} );
|
790 |
+
|
791 |
+
// end date picker ##
|
792 |
+
// might want to set minDate to something else, but not sure
|
793 |
+
// what would be best for everyone
|
794 |
+
jQuery('.updated-datepicker').datepicker( {
|
795 |
+
dateFormat : '<?php echo $date_format; ?>',
|
796 |
+
minDate : '<?php echo substr( $dates["0"]->first, 0, 10 ); ?>',
|
797 |
+
maxDate : '0',
|
798 |
+
firstDay : '<?php echo $start_of_week; ?>'
|
799 |
+
} );
|
800 |
+
|
801 |
+
});
|
802 |
+
|
803 |
+
</script>
|
804 |
+
<?php
|
805 |
+
|
806 |
+
}
|
807 |
+
|
808 |
+
|
809 |
+
|
810 |
+
|
811 |
+
/**
|
812 |
+
* Inline CSS
|
813 |
+
*
|
814 |
+
* @since 0.8.2
|
815 |
+
*/
|
816 |
+
public static function css()
|
817 |
+
{
|
818 |
+
|
819 |
+
// load the scripts on only the plugin admin page
|
820 |
+
if (
|
821 |
+
! isset( $_GET['page'] )
|
822 |
+
|| $_GET['page'] != 'q-report'
|
823 |
+
) {
|
824 |
+
|
825 |
+
return false;
|
826 |
+
|
827 |
+
}
|
828 |
+
|
829 |
+
?>
|
830 |
+
<style>
|
831 |
+
.toggleable { display: none; }
|
832 |
+
.hidden { display: none; }
|
833 |
+
</style>
|
834 |
+
<?php
|
835 |
+
|
836 |
+
}
|
837 |
+
|
838 |
+
}
|
library/admin/css/image/switch.png
ADDED
Binary file
|
library/admin/css/q-report.css
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
export-user-data.css
|
3 |
+
|
4 |
+
@since 0.9.6
|
5 |
+
*/
|
6 |
+
|
7 |
+
|
8 |
+
/* general layout */
|
9 |
+
|
10 |
+
.form-table tr.remember div.row:first-child {
|
11 |
+
margin-bottom: 10px;
|
12 |
+
}
|
13 |
+
|
14 |
+
.form-table tr.remember input.button-primary {
|
15 |
+
margin-left: 5px;
|
16 |
+
}
|
17 |
+
|
18 |
+
.form-table tr.remember select {
|
19 |
+
width: 25em;
|
20 |
+
}
|
21 |
+
|
22 |
+
input.error {
|
23 |
+
background: #D54E21;
|
24 |
+
color: #fff;
|
25 |
+
border: 1px solid #CCC;
|
26 |
+
}
|
27 |
+
|
28 |
+
th p.filter {
|
29 |
+
width: 100%;
|
30 |
+
}
|
31 |
+
|
32 |
+
/* form inputs */
|
33 |
+
|
34 |
+
|
35 |
+
/* multiselects */
|
36 |
+
|
37 |
+
.ms-container{
|
38 |
+
background: transparent url('image/switch.png') no-repeat 50% 50%;
|
39 |
+
/* width: 600px; */
|
40 |
+
}
|
41 |
+
|
42 |
+
.ms-container:after{
|
43 |
+
content: ".";
|
44 |
+
display: block;
|
45 |
+
height: 0;
|
46 |
+
line-height: 0;
|
47 |
+
font-size: 0;
|
48 |
+
clear: both;
|
49 |
+
min-height: 0;
|
50 |
+
visibility: hidden;
|
51 |
+
}
|
52 |
+
|
53 |
+
.ms-container .ms-selectable, .ms-container .ms-selection{
|
54 |
+
background: #fff;
|
55 |
+
color: #555555;
|
56 |
+
float: left;
|
57 |
+
width: 45%;
|
58 |
+
}
|
59 |
+
|
60 |
+
.ms-container .ms-list{
|
61 |
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
62 |
+
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
63 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
64 |
+
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
|
65 |
+
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
|
66 |
+
-ms-transition: border linear 0.2s, box-shadow linear 0.2s;
|
67 |
+
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
|
68 |
+
transition: border linear 0.2s, box-shadow linear 0.2s;
|
69 |
+
border: 1px solid #ccc;
|
70 |
+
-webkit-border-radius: 3px;
|
71 |
+
-moz-border-radius: 3px;
|
72 |
+
border-radius: 3px;
|
73 |
+
position: relative;
|
74 |
+
height: 134px;
|
75 |
+
padding: 0;
|
76 |
+
overflow-y: auto;
|
77 |
+
overflow-x: hidden;
|
78 |
+
}
|
79 |
+
|
80 |
+
.ms-container .ms-selectable{
|
81 |
+
margin-right: 10%;
|
82 |
+
}
|
83 |
+
|
84 |
+
.ms-container .ms-list.ms-focus{
|
85 |
+
border-color: rgba(82, 168, 236, 0.8);
|
86 |
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
87 |
+
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
88 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
89 |
+
outline: 0;
|
90 |
+
outline: thin dotted \9;
|
91 |
+
}
|
92 |
+
|
93 |
+
.ms-container ul{
|
94 |
+
margin: 0;
|
95 |
+
list-style-type: none;
|
96 |
+
padding: 0;
|
97 |
+
}
|
98 |
+
|
99 |
+
.ms-container .ms-optgroup-container{
|
100 |
+
width: 100%;
|
101 |
+
}
|
102 |
+
|
103 |
+
.ms-container .ms-optgroup-label{
|
104 |
+
margin: 0;
|
105 |
+
padding: 5px 0px 0px 5px;
|
106 |
+
cursor: pointer;
|
107 |
+
color: #999;
|
108 |
+
}
|
109 |
+
|
110 |
+
.ms-container .ms-selectable li.ms-elem-selectable,
|
111 |
+
.ms-container .ms-selection li.ms-elem-selection{
|
112 |
+
border-bottom: 1px #eee solid;
|
113 |
+
padding: 4px 10px;
|
114 |
+
color: #555;
|
115 |
+
font-size: 14px;
|
116 |
+
margin-bottom: 0px;
|
117 |
+
}
|
118 |
+
|
119 |
+
.ms-container .ms-selectable li.ms-hover,
|
120 |
+
.ms-container .ms-selection li.ms-hover{
|
121 |
+
cursor: pointer;
|
122 |
+
color: #fff;
|
123 |
+
text-decoration: none;
|
124 |
+
background-color: #08c;
|
125 |
+
margin-bottom: 0px;
|
126 |
+
}
|
127 |
+
|
128 |
+
.ms-container .ms-selectable li.disabled,
|
129 |
+
.ms-container .ms-selection li.disabled{
|
130 |
+
background-color: #eee;
|
131 |
+
color: #aaa;
|
132 |
+
cursor: text;
|
133 |
+
margin-bottom: 0px;
|
134 |
+
}
|
library/admin/javascript/jquery.multi-select.js
ADDED
@@ -0,0 +1,470 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* MultiSelect v0.9.8
|
3 |
+
* Copyright (c) 2012 Louis Cuny
|
4 |
+
*
|
5 |
+
* This program is free software. It comes without any warranty, to
|
6 |
+
* the extent permitted by applicable law. You can redistribute it
|
7 |
+
* and/or modify it under the terms of the Do What The Fuck You Want
|
8 |
+
* To Public License, Version 2, as published by Sam Hocevar. See
|
9 |
+
* http://sam.zoy.org/wtfpl/COPYING for more details.
|
10 |
+
*/
|
11 |
+
|
12 |
+
!function ($) {
|
13 |
+
|
14 |
+
"use strict";
|
15 |
+
|
16 |
+
|
17 |
+
/* MULTISELECT CLASS DEFINITION
|
18 |
+
* ====================== */
|
19 |
+
|
20 |
+
var MultiSelect = function (element, options) {
|
21 |
+
this.options = options;
|
22 |
+
this.$element = $(element);
|
23 |
+
|
24 |
+
this.$container = $('<div/>', { 'class': "ms-container" });
|
25 |
+
this.$selectableContainer = $('<div/>', { 'class': 'ms-selectable' });
|
26 |
+
this.$selectionContainer = $('<div/>', { 'class': 'ms-selection' });
|
27 |
+
this.$selectableUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
|
28 |
+
this.$selectionUl = $('<ul/>', { 'class': "ms-list", 'tabindex' : '-1' });
|
29 |
+
this.scrollTo = 0;
|
30 |
+
this.sanitizeRegexp = new RegExp("\\W+", 'gi');
|
31 |
+
this.elemsSelector = 'li:visible:not(.ms-optgroup-label,.ms-optgroup-container,.'+options.disabledClass+')';
|
32 |
+
};
|
33 |
+
|
34 |
+
MultiSelect.prototype = {
|
35 |
+
constructor: MultiSelect,
|
36 |
+
|
37 |
+
init: function(){
|
38 |
+
var that = this,
|
39 |
+
ms = this.$element;
|
40 |
+
|
41 |
+
if (ms.next('.ms-container').length === 0){
|
42 |
+
ms.css({ position: 'absolute', left: '-9999px' });
|
43 |
+
ms.attr('id', ms.attr('id') ? ms.attr('id') : Math.ceil(Math.random()*1000)+'multiselect');
|
44 |
+
this.$container.attr('id', 'ms-'+ms.attr('id'));
|
45 |
+
|
46 |
+
ms.find('option').each(function(){
|
47 |
+
that.generateLisFromOption(this);
|
48 |
+
});
|
49 |
+
|
50 |
+
this.$selectionUl.find('.ms-optgroup-label').hide();
|
51 |
+
|
52 |
+
if (that.options.selectableHeader){
|
53 |
+
that.$selectableContainer.append(that.options.selectableHeader);
|
54 |
+
}
|
55 |
+
that.$selectableContainer.append(that.$selectableUl);
|
56 |
+
if (that.options.selectableFooter){
|
57 |
+
that.$selectableContainer.append(that.options.selectableFooter);
|
58 |
+
}
|
59 |
+
|
60 |
+
if (that.options.selectionHeader){
|
61 |
+
that.$selectionContainer.append(that.options.selectionHeader);
|
62 |
+
}
|
63 |
+
that.$selectionContainer.append(that.$selectionUl);
|
64 |
+
if (that.options.selectionFooter){
|
65 |
+
that.$selectionContainer.append(that.options.selectionFooter);
|
66 |
+
}
|
67 |
+
|
68 |
+
that.$container.append(that.$selectableContainer);
|
69 |
+
that.$container.append(that.$selectionContainer);
|
70 |
+
ms.after(that.$container);
|
71 |
+
|
72 |
+
that.activeMouse(that.$selectableUl);
|
73 |
+
that.activeKeyboard(that.$selectableUl);
|
74 |
+
|
75 |
+
var action = that.options.dblClick ? 'dblclick' : 'click';
|
76 |
+
|
77 |
+
that.$selectableUl.on(action, '.ms-elem-selectable', function(){
|
78 |
+
that.select($(this).data('ms-value'));
|
79 |
+
});
|
80 |
+
that.$selectionUl.on(action, '.ms-elem-selection', function(){
|
81 |
+
that.deselect($(this).data('ms-value'));
|
82 |
+
});
|
83 |
+
|
84 |
+
that.activeMouse(that.$selectionUl);
|
85 |
+
that.activeKeyboard(that.$selectionUl);
|
86 |
+
|
87 |
+
ms.on('focus', function(){
|
88 |
+
that.$selectableUl.focus();
|
89 |
+
})
|
90 |
+
}
|
91 |
+
|
92 |
+
var selectedValues = ms.find('option:selected').map(function(){ return $(this).val(); }).get();
|
93 |
+
that.select(selectedValues, 'init');
|
94 |
+
|
95 |
+
if (typeof that.options.afterInit === 'function') {
|
96 |
+
that.options.afterInit.call(this, this.$container);
|
97 |
+
}
|
98 |
+
},
|
99 |
+
|
100 |
+
'generateLisFromOption' : function(option){
|
101 |
+
var that = this,
|
102 |
+
ms = that.$element,
|
103 |
+
attributes = "",
|
104 |
+
$option = $(option);
|
105 |
+
|
106 |
+
for (var cpt = 0; cpt < option.attributes.length; cpt++){
|
107 |
+
var attr = option.attributes[cpt];
|
108 |
+
|
109 |
+
if(attr.name !== 'value'){
|
110 |
+
attributes += attr.name+'="'+attr.value+'" ';
|
111 |
+
}
|
112 |
+
}
|
113 |
+
var selectableLi = $('<li '+attributes+'><span>'+$option.text()+'</span></li>'),
|
114 |
+
selectedLi = selectableLi.clone(),
|
115 |
+
value = $option.val(),
|
116 |
+
elementId = that.sanitize(value, that.sanitizeRegexp);
|
117 |
+
|
118 |
+
selectableLi
|
119 |
+
.data('ms-value', value)
|
120 |
+
.addClass('ms-elem-selectable')
|
121 |
+
.attr('id', elementId+'-selectable');
|
122 |
+
|
123 |
+
selectedLi
|
124 |
+
.data('ms-value', value)
|
125 |
+
.addClass('ms-elem-selection')
|
126 |
+
.attr('id', elementId+'-selection')
|
127 |
+
.hide();
|
128 |
+
|
129 |
+
if ($option.prop('disabled') || ms.prop('disabled')){
|
130 |
+
selectedLi.addClass(that.options.disabledClass);
|
131 |
+
selectableLi.addClass(that.options.disabledClass);
|
132 |
+
}
|
133 |
+
|
134 |
+
var $optgroup = $option.parent('optgroup');
|
135 |
+
|
136 |
+
if ($optgroup.length > 0){
|
137 |
+
var optgroupLabel = $optgroup.attr('label'),
|
138 |
+
optgroupId = that.sanitize(optgroupLabel, that.sanitizeRegexp),
|
139 |
+
$selectableOptgroup = that.$selectableUl.find('#optgroup-selectable-'+optgroupId),
|
140 |
+
$selectionOptgroup = that.$selectionUl.find('#optgroup-selection-'+optgroupId);
|
141 |
+
|
142 |
+
if ($selectableOptgroup.length === 0){
|
143 |
+
var optgroupContainerTpl = '<li class="ms-optgroup-container"></li>',
|
144 |
+
optgroupTpl = '<ul class="ms-optgroup"><li class="ms-optgroup-label"><span>'+optgroupLabel+'</span></li></ul>';
|
145 |
+
|
146 |
+
$selectableOptgroup = $(optgroupContainerTpl);
|
147 |
+
$selectionOptgroup = $(optgroupContainerTpl);
|
148 |
+
$selectableOptgroup.attr('id', 'optgroup-selectable-'+optgroupId);
|
149 |
+
$selectionOptgroup.attr('id', 'optgroup-selection-'+optgroupId);
|
150 |
+
$selectableOptgroup.append($(optgroupTpl));
|
151 |
+
$selectionOptgroup.append($(optgroupTpl));
|
152 |
+
if (that.options.selectableOptgroup){
|
153 |
+
$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
|
154 |
+
var values = $optgroup.children(':not(:selected)').map(function(){ return $(this).val() }).get();
|
155 |
+
that.select(values);
|
156 |
+
});
|
157 |
+
$selectionOptgroup.find('.ms-optgroup-label').on('click', function(){
|
158 |
+
var values = $optgroup.children(':selected').map(function(){ return $(this).val() }).get();
|
159 |
+
that.deselect(values);
|
160 |
+
});
|
161 |
+
}
|
162 |
+
that.$selectableUl.append($selectableOptgroup);
|
163 |
+
that.$selectionUl.append($selectionOptgroup);
|
164 |
+
}
|
165 |
+
$selectableOptgroup.children().append(selectableLi);
|
166 |
+
$selectionOptgroup.children().append(selectedLi);
|
167 |
+
} else {
|
168 |
+
that.$selectableUl.append(selectableLi);
|
169 |
+
that.$selectionUl.append(selectedLi);
|
170 |
+
}
|
171 |
+
},
|
172 |
+
|
173 |
+
'activeKeyboard' : function($list){
|
174 |
+
var that = this;
|
175 |
+
|
176 |
+
$list.on('focus', function(){
|
177 |
+
$(this).addClass('ms-focus');
|
178 |
+
})
|
179 |
+
.on('blur', function(){
|
180 |
+
$(this).removeClass('ms-focus');
|
181 |
+
})
|
182 |
+
.on('keydown', function(e){
|
183 |
+
switch (e.which) {
|
184 |
+
case 40:
|
185 |
+
case 38:
|
186 |
+
e.preventDefault();
|
187 |
+
e.stopPropagation();
|
188 |
+
that.moveHighlight($(this), (e.which === 38) ? -1 : 1);
|
189 |
+
return;
|
190 |
+
case 32:
|
191 |
+
e.preventDefault();
|
192 |
+
e.stopPropagation();
|
193 |
+
that.selectHighlighted($list);
|
194 |
+
return;
|
195 |
+
case 37:
|
196 |
+
case 39:
|
197 |
+
e.preventDefault();
|
198 |
+
e.stopPropagation();
|
199 |
+
that.switchList($list);
|
200 |
+
return;
|
201 |
+
}
|
202 |
+
});
|
203 |
+
},
|
204 |
+
|
205 |
+
'moveHighlight': function($list, direction){
|
206 |
+
var $elems = $list.find(this.elemsSelector),
|
207 |
+
$currElem = $elems.filter('.ms-hover'),
|
208 |
+
$nextElem = null,
|
209 |
+
elemHeight = $elems.first().outerHeight(),
|
210 |
+
containerHeight = $list.height(),
|
211 |
+
containerSelector = '#'+this.$container.prop('id');
|
212 |
+
|
213 |
+
// Deactive mouseenter event when move is active
|
214 |
+
// It fixes a bug when mouse is over the list
|
215 |
+
$elems.off('mouseenter');
|
216 |
+
|
217 |
+
$elems.removeClass('ms-hover');
|
218 |
+
if (direction === 1){ // DOWN
|
219 |
+
|
220 |
+
$nextElem = $currElem.nextAll(this.elemsSelector).first();
|
221 |
+
if ($nextElem.length === 0){
|
222 |
+
var $optgroupUl = $currElem.parent();
|
223 |
+
|
224 |
+
if ($optgroupUl.hasClass('ms-optgroup')){
|
225 |
+
var $optgroupLi = $optgroupUl.parent(),
|
226 |
+
$nextOptgroupLi = $optgroupLi.next(':visible');
|
227 |
+
|
228 |
+
if ($nextOptgroupLi.length > 0){
|
229 |
+
$nextElem = $nextOptgroupLi.find(this.elemsSelector).first();
|
230 |
+
} else {
|
231 |
+
$nextElem = $elems.first();
|
232 |
+
}
|
233 |
+
} else {
|
234 |
+
$nextElem = $elems.first();
|
235 |
+
}
|
236 |
+
}
|
237 |
+
} else if (direction === -1){ // UP
|
238 |
+
|
239 |
+
$nextElem = $currElem.prevAll(this.elemsSelector).first();
|
240 |
+
if ($nextElem.length === 0){
|
241 |
+
var $optgroupUl = $currElem.parent();
|
242 |
+
|
243 |
+
if ($optgroupUl.hasClass('ms-optgroup')){
|
244 |
+
var $optgroupLi = $optgroupUl.parent(),
|
245 |
+
$prevOptgroupLi = $optgroupLi.prev(':visible');
|
246 |
+
|
247 |
+
if ($prevOptgroupLi.length > 0){
|
248 |
+
$nextElem = $prevOptgroupLi.find(this.elemsSelector).last();
|
249 |
+
} else {
|
250 |
+
$nextElem = $elems.last();
|
251 |
+
}
|
252 |
+
} else {
|
253 |
+
$nextElem = $elems.last();
|
254 |
+
}
|
255 |
+
}
|
256 |
+
}
|
257 |
+
if ($nextElem.length > 0){
|
258 |
+
$nextElem.addClass('ms-hover');
|
259 |
+
var scrollTo = $list.scrollTop() + $nextElem.position().top -
|
260 |
+
containerHeight / 2 + elemHeight / 2;
|
261 |
+
|
262 |
+
$list.scrollTop(scrollTo);
|
263 |
+
}
|
264 |
+
},
|
265 |
+
|
266 |
+
'selectHighlighted' : function($list){
|
267 |
+
var $elems = $list.find(this.elemsSelector),
|
268 |
+
$highlightedElem = $elems.filter('.ms-hover').first();
|
269 |
+
|
270 |
+
if ($highlightedElem.length > 0){
|
271 |
+
if ($list.parent().hasClass('ms-selectable')){
|
272 |
+
this.select($highlightedElem.data('ms-value'));
|
273 |
+
} else {
|
274 |
+
this.deselect($highlightedElem.data('ms-value'));
|
275 |
+
}
|
276 |
+
$elems.removeClass('ms-hover');
|
277 |
+
}
|
278 |
+
},
|
279 |
+
|
280 |
+
'switchList' : function($list){
|
281 |
+
$list.blur();
|
282 |
+
if ($list.parent().hasClass('ms-selectable')){
|
283 |
+
this.$selectionUl.focus();
|
284 |
+
} else {
|
285 |
+
this.$selectableUl.focus();
|
286 |
+
}
|
287 |
+
},
|
288 |
+
|
289 |
+
'activeMouse' : function($list){
|
290 |
+
var that = this;
|
291 |
+
|
292 |
+
$list.on('mousemove', function(){
|
293 |
+
var elems = $list.find(that.elemsSelector);
|
294 |
+
|
295 |
+
elems.on('mouseenter', function(){
|
296 |
+
elems.removeClass('ms-hover');
|
297 |
+
$(this).addClass('ms-hover');
|
298 |
+
});
|
299 |
+
});
|
300 |
+
},
|
301 |
+
|
302 |
+
'refresh' : function() {
|
303 |
+
this.destroy();
|
304 |
+
this.$element.multiSelect(this.options);
|
305 |
+
},
|
306 |
+
|
307 |
+
'destroy' : function(){
|
308 |
+
$("#ms-"+this.$element.attr("id")).remove();
|
309 |
+
this.$element.removeData('multiselect');
|
310 |
+
},
|
311 |
+
|
312 |
+
'select' : function(value, method){
|
313 |
+
if (typeof value === 'string'){ value = [value]; }
|
314 |
+
|
315 |
+
var that = this,
|
316 |
+
ms = this.$element,
|
317 |
+
msIds = $.map(value, function(val){ return(that.sanitize(val, that.sanitizeRegexp)); }),
|
318 |
+
selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable').filter(':not(.'+that.options.disabledClass+')'),
|
319 |
+
selections = this.$selectionUl.find('#' + msIds.join('-selection, #') + '-selection').filter(':not(.'+that.options.disabledClass+')'),
|
320 |
+
options = ms.find('option:not(:disabled)').filter(function(){ return($.inArray(this.value, value) > -1); });
|
321 |
+
|
322 |
+
if (selectables.length > 0){
|
323 |
+
selectables.addClass('ms-selected').hide();
|
324 |
+
selections.addClass('ms-selected').show();
|
325 |
+
options.prop('selected', true);
|
326 |
+
|
327 |
+
var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
|
328 |
+
if (selectableOptgroups.length > 0){
|
329 |
+
selectableOptgroups.each(function(){
|
330 |
+
var selectablesLi = $(this).find('.ms-elem-selectable');
|
331 |
+
if (selectablesLi.length === selectablesLi.filter('.ms-selected').length){
|
332 |
+
$(this).find('.ms-optgroup-label').hide();
|
333 |
+
}
|
334 |
+
});
|
335 |
+
|
336 |
+
var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
|
337 |
+
selectionOptgroups.each(function(){
|
338 |
+
var selectionsLi = $(this).find('.ms-elem-selection');
|
339 |
+
if (selectionsLi.filter('.ms-selected').length > 0){
|
340 |
+
$(this).find('.ms-optgroup-label').show();
|
341 |
+
}
|
342 |
+
});
|
343 |
+
} else {
|
344 |
+
if (that.options.keepOrder){
|
345 |
+
var selectionLiLast = that.$selectionUl.find('.ms-selected');
|
346 |
+
if((selectionLiLast.length > 1) && (selectionLiLast.last().get(0) != selections.get(0))) {
|
347 |
+
selections.insertAfter(selectionLiLast.last());
|
348 |
+
}
|
349 |
+
}
|
350 |
+
}
|
351 |
+
if (method !== 'init'){
|
352 |
+
ms.trigger('change');
|
353 |
+
if (typeof that.options.afterSelect === 'function') {
|
354 |
+
that.options.afterSelect.call(this, value);
|
355 |
+
}
|
356 |
+
}
|
357 |
+
}
|
358 |
+
},
|
359 |
+
|
360 |
+
'deselect' : function(value){
|
361 |
+
if (typeof value === 'string'){ value = [value]; }
|
362 |
+
|
363 |
+
var that = this,
|
364 |
+
ms = this.$element,
|
365 |
+
msIds = $.map(value, function(val){ return(that.sanitize(val, that.sanitizeRegexp)); }),
|
366 |
+
selectables = this.$selectableUl.find('#' + msIds.join('-selectable, #')+'-selectable'),
|
367 |
+
selections = this.$selectionUl.find('#' + msIds.join('-selection, #')+'-selection').filter('.ms-selected'),
|
368 |
+
options = ms.find('option').filter(function(){ return($.inArray(this.value, value) > -1); });
|
369 |
+
|
370 |
+
if (selections.length > 0){
|
371 |
+
selectables.removeClass('ms-selected').show();
|
372 |
+
selections.removeClass('ms-selected').hide();
|
373 |
+
options.prop('selected', false);
|
374 |
+
|
375 |
+
var selectableOptgroups = that.$selectableUl.children('.ms-optgroup-container');
|
376 |
+
if (selectableOptgroups.length > 0){
|
377 |
+
selectableOptgroups.each(function(){
|
378 |
+
var selectablesLi = $(this).find('.ms-elem-selectable');
|
379 |
+
if (selectablesLi.filter(':not(.ms-selected)').length > 0){
|
380 |
+
$(this).find('.ms-optgroup-label').show();
|
381 |
+
}
|
382 |
+
});
|
383 |
+
|
384 |
+
var selectionOptgroups = that.$selectionUl.children('.ms-optgroup-container');
|
385 |
+
selectionOptgroups.each(function(){
|
386 |
+
var selectionsLi = $(this).find('.ms-elem-selection');
|
387 |
+
if (selectionsLi.filter('.ms-selected').length === 0){
|
388 |
+
$(this).find('.ms-optgroup-label').hide();
|
389 |
+
}
|
390 |
+
});
|
391 |
+
}
|
392 |
+
ms.trigger('change');
|
393 |
+
if (typeof that.options.afterDeselect === 'function') {
|
394 |
+
that.options.afterDeselect.call(this, value);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
},
|
398 |
+
|
399 |
+
'select_all' : function(){
|
400 |
+
var ms = this.$element,
|
401 |
+
values = ms.val();
|
402 |
+
|
403 |
+
ms.find('option:not(":disabled")').prop('selected', true);
|
404 |
+
this.$selectableUl.find('.ms-elem-selectable').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').hide();
|
405 |
+
this.$selectionUl.find('.ms-optgroup-label').show();
|
406 |
+
this.$selectableUl.find('.ms-optgroup-label').hide();
|
407 |
+
this.$selectionUl.find('.ms-elem-selection').filter(':not(.'+this.options.disabledClass+')').addClass('ms-selected').show();
|
408 |
+
this.$selectionUl.focus();
|
409 |
+
ms.trigger('change');
|
410 |
+
if (typeof this.options.afterSelect === 'function') {
|
411 |
+
var selectedValues = $.grep(ms.val(), function(item){
|
412 |
+
return $.inArray(item, values) < 0;
|
413 |
+
});
|
414 |
+
this.options.afterSelect.call(this, selectedValues);
|
415 |
+
}
|
416 |
+
},
|
417 |
+
|
418 |
+
'deselect_all' : function(){
|
419 |
+
var ms = this.$element,
|
420 |
+
values = ms.val();
|
421 |
+
|
422 |
+
ms.find('option').prop('selected', false);
|
423 |
+
this.$selectableUl.find('.ms-elem-selectable').removeClass('ms-selected').show();
|
424 |
+
this.$selectionUl.find('.ms-optgroup-label').hide();
|
425 |
+
this.$selectableUl.find('.ms-optgroup-label').show();
|
426 |
+
this.$selectionUl.find('.ms-elem-selection').removeClass('ms-selected').hide();
|
427 |
+
this.$selectableUl.focus();
|
428 |
+
ms.trigger('change');
|
429 |
+
if (typeof this.options.afterDeselect === 'function') {
|
430 |
+
this.options.afterDeselect.call(this, values);
|
431 |
+
}
|
432 |
+
},
|
433 |
+
|
434 |
+
sanitize: function(value, reg){
|
435 |
+
return(value.replace(reg, '_'));
|
436 |
+
}
|
437 |
+
};
|
438 |
+
|
439 |
+
/* MULTISELECT PLUGIN DEFINITION
|
440 |
+
* ======================= */
|
441 |
+
|
442 |
+
$.fn.multiSelect = function () {
|
443 |
+
var option = arguments[0],
|
444 |
+
args = arguments;
|
445 |
+
|
446 |
+
return this.each(function () {
|
447 |
+
var $this = $(this),
|
448 |
+
data = $this.data('multiselect'),
|
449 |
+
options = $.extend({}, $.fn.multiSelect.defaults, $this.data(), typeof option === 'object' && option);
|
450 |
+
|
451 |
+
if (!data){ $this.data('multiselect', (data = new MultiSelect(this, options))); }
|
452 |
+
|
453 |
+
if (typeof option === 'string'){
|
454 |
+
data[option](args[1]);
|
455 |
+
} else {
|
456 |
+
data.init();
|
457 |
+
}
|
458 |
+
});
|
459 |
+
};
|
460 |
+
|
461 |
+
$.fn.multiSelect.defaults = {
|
462 |
+
selectableOptgroup: false,
|
463 |
+
disabledClass : 'disabled',
|
464 |
+
dblClick : false,
|
465 |
+
keepOrder: false
|
466 |
+
};
|
467 |
+
|
468 |
+
$.fn.multiSelect.Constructor = MultiSelect;
|
469 |
+
|
470 |
+
}(window.jQuery);
|
library/api/admin.php
ADDED
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\api;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
#\q\report\api\admin::run();
|
10 |
+
|
11 |
+
class admin extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// load standard fields ##
|
19 |
+
#\add_action( 'admin_init', array( get_class(), 'load' ), 1 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Render admin fields
|
29 |
+
*
|
30 |
+
* @since 2.0.0.
|
31 |
+
* @return HTML
|
32 |
+
*/
|
33 |
+
public static function render( $array = null )
|
34 |
+
{
|
35 |
+
|
36 |
+
// check if we have any fields to show ##
|
37 |
+
if (
|
38 |
+
is_null( $array )
|
39 |
+
|| ! is_array( $array )
|
40 |
+
) {
|
41 |
+
|
42 |
+
#helper::log( 'No fields found' );
|
43 |
+
|
44 |
+
return false;
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
#helper::log( $array );
|
49 |
+
|
50 |
+
// check that we have all required arrays ##
|
51 |
+
if (
|
52 |
+
! $array['title'] // string ##
|
53 |
+
|| ! $array['label'] // lowercase string ##
|
54 |
+
|| ! $array['type']
|
55 |
+
#|| ! $array['description']
|
56 |
+
) {
|
57 |
+
|
58 |
+
#helper::log( 'Missing data' );
|
59 |
+
|
60 |
+
return false;
|
61 |
+
|
62 |
+
}
|
63 |
+
|
64 |
+
// is this toggleable ? ##
|
65 |
+
$toggleable = false === $array['title'] ? 'standard' : 'toggleable' ;
|
66 |
+
|
67 |
+
// keep labels formatted nicely ##
|
68 |
+
$array['label'] = \sanitize_key( $array['label'] );
|
69 |
+
|
70 |
+
#helper::log( $array['options'] );
|
71 |
+
|
72 |
+
// build out options ##
|
73 |
+
if ( ! self::has_options( $array ) ) {
|
74 |
+
|
75 |
+
#helper::log( 'Missing options for: '.$array['label'] );
|
76 |
+
|
77 |
+
return false;
|
78 |
+
|
79 |
+
}
|
80 |
+
|
81 |
+
?>
|
82 |
+
<tr valign="top" class="<?php echo $toggleable; ?>">
|
83 |
+
<th scope="row"><label for="q_report_<?php echo $array['label']; ?>"><?php echo $array['title']; ?></label></th>
|
84 |
+
<td>
|
85 |
+
<?php
|
86 |
+
|
87 |
+
// options ##
|
88 |
+
self::build_options( $array );
|
89 |
+
|
90 |
+
// do we have a description ? ##
|
91 |
+
if ( isset( $array['description'] ) ) {
|
92 |
+
|
93 |
+
?>
|
94 |
+
<p class="description"><?php echo $array['description']; ?></p>
|
95 |
+
<?php
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
?>
|
100 |
+
</td>
|
101 |
+
</tr>
|
102 |
+
<?php
|
103 |
+
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
public static function has_options( $array = null )
|
108 |
+
{
|
109 |
+
|
110 |
+
if (
|
111 |
+
is_null( $array )
|
112 |
+
|| ! is_array( $array )
|
113 |
+
|| ! isset( $array['options'] )
|
114 |
+
|| ! isset( $array['label'] )
|
115 |
+
|| ! is_array( $array['options'] )
|
116 |
+
|| ! isset( $array['options_ID'] )
|
117 |
+
|| ! isset( $array['options_title'] )
|
118 |
+
|| ! isset( $array['label_select'] )
|
119 |
+
) {
|
120 |
+
|
121 |
+
return false;
|
122 |
+
|
123 |
+
}
|
124 |
+
|
125 |
+
// crude ##
|
126 |
+
return true;
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
public static function build_options( $array = null )
|
133 |
+
{
|
134 |
+
|
135 |
+
if (
|
136 |
+
is_null( $array )
|
137 |
+
|| ! is_array( $array )
|
138 |
+
|| ! isset( $array['type'] )
|
139 |
+
) {
|
140 |
+
|
141 |
+
#helper::log( 'Error building options for: '.$array['label'] );
|
142 |
+
|
143 |
+
return false;
|
144 |
+
|
145 |
+
}
|
146 |
+
|
147 |
+
// start empty ##
|
148 |
+
$return = false;
|
149 |
+
|
150 |
+
switch ( $array['type'] ) {
|
151 |
+
|
152 |
+
case ( 'select' ) :
|
153 |
+
|
154 |
+
$return = self::field_select( $array );
|
155 |
+
|
156 |
+
break ;
|
157 |
+
|
158 |
+
}
|
159 |
+
|
160 |
+
// kick it back ##
|
161 |
+
return $return;
|
162 |
+
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
|
167 |
+
public static function field_select( $array = null )
|
168 |
+
{
|
169 |
+
|
170 |
+
if (
|
171 |
+
is_null( $array )
|
172 |
+
|| ! is_array( $array )
|
173 |
+
|| ! isset( $array['options'] )
|
174 |
+
|| ! isset( $array['label'] )
|
175 |
+
|| ! is_array( $array['options'] )
|
176 |
+
|| ! isset( $array['options_ID'] )
|
177 |
+
|| ! isset( $array['options_title'] )
|
178 |
+
|| ! isset( $array['label_select'] )
|
179 |
+
) {
|
180 |
+
|
181 |
+
#helper::log( 'Error building select options for: '.$array['label'] );
|
182 |
+
|
183 |
+
return false;
|
184 |
+
|
185 |
+
}
|
186 |
+
|
187 |
+
#helper::log( 'Building select options for: '.$array['label'] );
|
188 |
+
|
189 |
+
// is this a multiselect ? ##
|
190 |
+
$multiselect = isset( $array['multiselect'] ) ? ' multiple="multiple"' : '' ;
|
191 |
+
|
192 |
+
?>
|
193 |
+
<select <?php echo $multiselect; ?> name="<?php echo $array['label']; ?>" id="q_report_<?php echo $array['label']; ?>">
|
194 |
+
<?php
|
195 |
+
|
196 |
+
// label ##
|
197 |
+
echo '<option value="">'.$array['label_select'].'</option>';
|
198 |
+
|
199 |
+
// loop over all options ##
|
200 |
+
foreach ( $array['options'] as $item ) {
|
201 |
+
|
202 |
+
// id ##
|
203 |
+
$id = $item->{$array['options_ID']}; // ID
|
204 |
+
|
205 |
+
// title
|
206 |
+
$title = $item->{$array['options_title']}; // post_title ##
|
207 |
+
|
208 |
+
// check if option built ##
|
209 |
+
if (
|
210 |
+
! $id
|
211 |
+
|| ! $title
|
212 |
+
) {
|
213 |
+
|
214 |
+
continue;
|
215 |
+
|
216 |
+
}
|
217 |
+
|
218 |
+
?>
|
219 |
+
<option value='<?php echo \esc_attr( $id ); ?>'><?php echo $title; ?></option>
|
220 |
+
<?php
|
221 |
+
|
222 |
+
}
|
223 |
+
|
224 |
+
?>
|
225 |
+
</select>
|
226 |
+
<?php
|
227 |
+
|
228 |
+
}
|
229 |
+
|
230 |
+
|
231 |
+
}
|
library/core/buddypress.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
\q\report\core\buddypress::run();
|
10 |
+
|
11 |
+
class buddypress extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// load BP ##
|
19 |
+
\add_action( 'admin_init', array( get_class(), 'load' ), 1000001 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Get BP fields from DB, if BuddyPress is installed and active
|
28 |
+
*
|
29 |
+
* @since 2.0.0
|
30 |
+
*/
|
31 |
+
public static function get_fields()
|
32 |
+
{
|
33 |
+
|
34 |
+
// buddypress support deprecated for now ##
|
35 |
+
return false;
|
36 |
+
|
37 |
+
if ( ! function_exists ('bp_is_active') ) {
|
38 |
+
|
39 |
+
return false;
|
40 |
+
|
41 |
+
}
|
42 |
+
|
43 |
+
// introduce global class object ##
|
44 |
+
global $wpdb;
|
45 |
+
|
46 |
+
// grab all buddypress x profile fields ##
|
47 |
+
$bp_fields = $wpdb->get_results( "SELECT distinct(name) FROM ".$wpdb->base_prefix."bp_xprofile_fields WHERE parent_id = 0" );
|
48 |
+
|
49 |
+
// get name value from object ##
|
50 |
+
$bp_fields = \wp_list_pluck( $bp_fields, 'name' );
|
51 |
+
|
52 |
+
// test array ##
|
53 |
+
#helper::log( $bp_fields );
|
54 |
+
|
55 |
+
// allow array to be filtered ##
|
56 |
+
$bp_fields = \apply_filters( 'export_user_data_bp_fields', $bp_fields );
|
57 |
+
|
58 |
+
// kick it back ##
|
59 |
+
return $bp_fields;
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Load up saved exports for this user
|
67 |
+
* Set to public as hooked into action
|
68 |
+
*
|
69 |
+
* @since 0.9.6
|
70 |
+
* @return Array of saved exports
|
71 |
+
*/
|
72 |
+
public static function load()
|
73 |
+
{
|
74 |
+
|
75 |
+
// do we have a bp object in the globals ##
|
76 |
+
if (
|
77 |
+
\is_plugin_active( 'buddypress/bp-loader.php' ) // plugin active
|
78 |
+
&& function_exists ( 'buddypress' ) // loader function exists ##
|
79 |
+
&& ! isset( $GLOBALS['bp'] ) // but global unavailble ##
|
80 |
+
) {
|
81 |
+
|
82 |
+
helper::log( 'BP not loaded - calling buddypress()' );
|
83 |
+
|
84 |
+
// call BP
|
85 |
+
buddypress();
|
86 |
+
|
87 |
+
return true;
|
88 |
+
|
89 |
+
}
|
90 |
+
|
91 |
+
#self::log( 'BP loaded' );
|
92 |
+
|
93 |
+
return true;
|
94 |
+
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
}
|
library/core/config.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
// \q\report\core\config::run();
|
10 |
+
|
11 |
+
class config extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// load standard fields ##
|
19 |
+
\add_action( 'admin_init', array( get_class(), 'load' ), 1 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Load up saved exports for this user
|
29 |
+
* Set to public as hooked into action
|
30 |
+
*
|
31 |
+
* @since 0.9.6
|
32 |
+
* @return Array of saved exports
|
33 |
+
*/
|
34 |
+
public static function load()
|
35 |
+
{
|
36 |
+
|
37 |
+
// load api admin fields ##
|
38 |
+
self::get_admin_fields();
|
39 |
+
|
40 |
+
// kick it back ##
|
41 |
+
return true;
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Load up saved exports for this user
|
49 |
+
* Set to public as hooked into action
|
50 |
+
*
|
51 |
+
* @since 0.9.6
|
52 |
+
* @return Array of saved exports
|
53 |
+
*/
|
54 |
+
public static function get_admin_fields()
|
55 |
+
{
|
56 |
+
|
57 |
+
// build array ##
|
58 |
+
$array = array(
|
59 |
+
'program' => array(
|
60 |
+
'title' => \_e( 'Programs', 'export-user-data' ),
|
61 |
+
'label' => 'program',
|
62 |
+
'description' => \__( 'Select the program that you wish to export.', 'export-user-data' ),
|
63 |
+
'label_select' => \__( 'All Programs', 'export-user-data' ),
|
64 |
+
'options' => \get_posts( array( 'post_type'=> 'program', 'posts_per_page' => -1 ) ),
|
65 |
+
'options_ID' => 'ID',
|
66 |
+
'options_title' => 'post_title'
|
67 |
+
)
|
68 |
+
);
|
69 |
+
|
70 |
+
// test it ##
|
71 |
+
#self::log( $array );
|
72 |
+
|
73 |
+
// add to static property ##
|
74 |
+
self::$api_admin_fields = $array;
|
75 |
+
|
76 |
+
// filter and return ##
|
77 |
+
apply_filters( 'q/report/api/admin_fields', self::$api_admin_fields );
|
78 |
+
|
79 |
+
// test it ##
|
80 |
+
self::log( self::$api_admin_fields );
|
81 |
+
|
82 |
+
// kick it back ##
|
83 |
+
return true;
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
}
|
library/core/core.php
ADDED
@@ -0,0 +1,420 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
#\q\report\core\core::run();
|
10 |
+
|
11 |
+
class core extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// load user options ##
|
19 |
+
#\add_action( 'admin_init', array( get_class(), 'load_user_options' ), 1000002 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get the array of standard WP_User fields to return
|
29 |
+
*/
|
30 |
+
public static function get_user_fields()
|
31 |
+
{
|
32 |
+
|
33 |
+
// standard wp_users fields ##
|
34 |
+
if ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) {
|
35 |
+
|
36 |
+
// debug ##
|
37 |
+
#self::log( 'full' );
|
38 |
+
|
39 |
+
// exportable user data ##
|
40 |
+
$user_fields = array(
|
41 |
+
'ID'
|
42 |
+
, 'user_login'
|
43 |
+
#, 'user_pass'
|
44 |
+
, 'user_nicename'
|
45 |
+
, 'user_email'
|
46 |
+
, 'user_url'
|
47 |
+
, 'user_registered'
|
48 |
+
#, 'user_activation_key'
|
49 |
+
, 'user_status'
|
50 |
+
, 'display_name'
|
51 |
+
);
|
52 |
+
|
53 |
+
} else {
|
54 |
+
|
55 |
+
// debug ##
|
56 |
+
#self::log( 'reduced' );
|
57 |
+
|
58 |
+
// just return the user ID
|
59 |
+
$user_fields = array(
|
60 |
+
'ID'
|
61 |
+
);
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
// kick back values via filter ##
|
66 |
+
return \apply_filters( 'q/report/export/user_fields', $user_fields );
|
67 |
+
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Get the array of special user fields to return
|
75 |
+
*/
|
76 |
+
public static function get_special_fields()
|
77 |
+
{
|
78 |
+
|
79 |
+
// exportable user data ##
|
80 |
+
$special_fields = array(
|
81 |
+
# 'roles' // list of WP Roles
|
82 |
+
#, 'groups' // BP Groups
|
83 |
+
);
|
84 |
+
|
85 |
+
// should we allow groups ##
|
86 |
+
if ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] ) {
|
87 |
+
|
88 |
+
$special_fields[] = 'groups'; // add groups ##
|
89 |
+
|
90 |
+
}
|
91 |
+
|
92 |
+
// should we allow roles ##
|
93 |
+
if ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] ) {
|
94 |
+
|
95 |
+
$special_fields[] = 'roles'; // add groups ##
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
// kick back the array via filter ##
|
100 |
+
return \apply_filters( 'q/report/export/special_fields', $special_fields );
|
101 |
+
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Data to exclude from export
|
108 |
+
*/
|
109 |
+
public static function get_exclude_fields()
|
110 |
+
{
|
111 |
+
|
112 |
+
$exclude_fields = array (
|
113 |
+
'user_pass'
|
114 |
+
, 'q_eud_exports'
|
115 |
+
#, 'user_activation_key'
|
116 |
+
);
|
117 |
+
|
118 |
+
// kick back array via filter ##
|
119 |
+
return \apply_filters( 'q/report/export/exclude_fields', $exclude_fields );
|
120 |
+
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Return Byte count of $val
|
128 |
+
*
|
129 |
+
* @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
|
130 |
+
* @since 0.9.6
|
131 |
+
*/
|
132 |
+
public static function return_bytes( $val )
|
133 |
+
{
|
134 |
+
|
135 |
+
$val = trim( $val );
|
136 |
+
$last = strtolower($val[strlen($val)-1]);
|
137 |
+
switch( $last ) {
|
138 |
+
|
139 |
+
// The 'G' modifier is available since PHP 5.1.0
|
140 |
+
case 'g':
|
141 |
+
|
142 |
+
$val *= 1024;
|
143 |
+
|
144 |
+
case 'm':
|
145 |
+
|
146 |
+
$val *= 1024;
|
147 |
+
|
148 |
+
case 'k':
|
149 |
+
|
150 |
+
$val *= 1024;
|
151 |
+
|
152 |
+
}
|
153 |
+
|
154 |
+
return $val;
|
155 |
+
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Recursively implodes an array
|
161 |
+
*
|
162 |
+
* @since 1.0.1
|
163 |
+
* @access public
|
164 |
+
* @param array $array multi-dimensional array to recursively implode
|
165 |
+
* @param string $glue value that glues elements together
|
166 |
+
* @param bool $include_keys include keys before their values
|
167 |
+
* @param bool $trim_all trim ALL whitespace from string
|
168 |
+
* @return string imploded array
|
169 |
+
*/
|
170 |
+
public static function recursive_implode( $array, $return = null, $glue = '|' )
|
171 |
+
{
|
172 |
+
|
173 |
+
// unserialize ##
|
174 |
+
$array = self::unserialize( $array );
|
175 |
+
|
176 |
+
// kick it back ##
|
177 |
+
if ( is_null ( $return ) && ! is_array( $array ) ) {
|
178 |
+
|
179 |
+
return $array;
|
180 |
+
|
181 |
+
}
|
182 |
+
|
183 |
+
// empty return ##
|
184 |
+
if ( is_null ( $return ) ) {
|
185 |
+
|
186 |
+
$return = '';
|
187 |
+
|
188 |
+
} else {
|
189 |
+
|
190 |
+
if ( "||" == $glue ) {
|
191 |
+
|
192 |
+
$glue = '|||';
|
193 |
+
|
194 |
+
} else if ( "|" == $glue ) {
|
195 |
+
|
196 |
+
$glue = '||';
|
197 |
+
|
198 |
+
}
|
199 |
+
|
200 |
+
}
|
201 |
+
|
202 |
+
// loop ##
|
203 |
+
foreach( $array as $key => $value ) {
|
204 |
+
|
205 |
+
// unserialize ##
|
206 |
+
$value = self::unserialize( $value );
|
207 |
+
|
208 |
+
if( is_array( $value ) ) {
|
209 |
+
|
210 |
+
$return .= $glue . $key . $glue . self::recursive_implode( $value, $return, $glue );
|
211 |
+
|
212 |
+
} else {
|
213 |
+
|
214 |
+
$return .= $glue . $key . $glue . $value;
|
215 |
+
|
216 |
+
}
|
217 |
+
|
218 |
+
}
|
219 |
+
|
220 |
+
// Removes first $glue from string ##
|
221 |
+
if ( $glue && $return && $return[0] == '|' ) {
|
222 |
+
|
223 |
+
$return = ltrim( $return, '|' );
|
224 |
+
|
225 |
+
}
|
226 |
+
|
227 |
+
// Trim ALL whitespace ##
|
228 |
+
if ( $return ) {
|
229 |
+
|
230 |
+
$return = preg_replace( "/(\s)/ixsm", '', $return );
|
231 |
+
|
232 |
+
}
|
233 |
+
|
234 |
+
// kick it back ##
|
235 |
+
return $return;
|
236 |
+
|
237 |
+
}
|
238 |
+
|
239 |
+
|
240 |
+
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Save Unserializer
|
244 |
+
*
|
245 |
+
* @since 1.1.4
|
246 |
+
*/
|
247 |
+
public static function unserialize( $value = null )
|
248 |
+
{
|
249 |
+
|
250 |
+
// the $value is serialized ##
|
251 |
+
if ( \is_serialized( $value ) ) {
|
252 |
+
|
253 |
+
// unserliaze to new variable ##
|
254 |
+
$unserialized = @unserialize( $value );
|
255 |
+
|
256 |
+
// test if unserliazing produced errors ##
|
257 |
+
if ( $unserialized !== false || $value == 'b:0;' ) {
|
258 |
+
|
259 |
+
#$value = 'UNSERIALIZED_'.$unserialized;
|
260 |
+
$value = $unserialized;
|
261 |
+
|
262 |
+
} else {
|
263 |
+
|
264 |
+
// failed to unserialize - data potentially corrupted in db ##
|
265 |
+
#$value = 'NOT_SERIALIZED_'.$value;
|
266 |
+
$value = $value;
|
267 |
+
|
268 |
+
}
|
269 |
+
|
270 |
+
}
|
271 |
+
|
272 |
+
// kick it back ##
|
273 |
+
return $value;
|
274 |
+
|
275 |
+
}
|
276 |
+
|
277 |
+
|
278 |
+
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Encode special characters
|
282 |
+
*
|
283 |
+
* @param type $string
|
284 |
+
* @return string Encoding string
|
285 |
+
* @since 1.2.3
|
286 |
+
*/
|
287 |
+
public static function format_value( $string = null )
|
288 |
+
{
|
289 |
+
|
290 |
+
// sanity check ##
|
291 |
+
if ( is_null( $string ) ) {
|
292 |
+
|
293 |
+
return false;
|
294 |
+
|
295 |
+
}
|
296 |
+
|
297 |
+
// kick it back in a nicer format ##
|
298 |
+
#return htmlentities( $string, ENT_COMPAT, 'UTF-8' );
|
299 |
+
|
300 |
+
// kick it back via a filter to allow custom formatting ##
|
301 |
+
return \apply_filters( 'q/report/export/format_value', $string );
|
302 |
+
|
303 |
+
}
|
304 |
+
|
305 |
+
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Quote array elements and separate with commas
|
309 |
+
*
|
310 |
+
* @since 0.9.6
|
311 |
+
* @return String
|
312 |
+
*/
|
313 |
+
public static function quote_array( $array )
|
314 |
+
{
|
315 |
+
|
316 |
+
$prefix = ''; // starts empty ##
|
317 |
+
$elementlist = '';
|
318 |
+
|
319 |
+
if ( is_array( $array ) ) {
|
320 |
+
|
321 |
+
foreach( $array as $element ) {
|
322 |
+
|
323 |
+
$elementlist .= $prefix . "'" . $element . "'";
|
324 |
+
$prefix = ','; // prefix all remaining items with a comma ##
|
325 |
+
|
326 |
+
}
|
327 |
+
|
328 |
+
}
|
329 |
+
|
330 |
+
// kick back string to function caller ##
|
331 |
+
return( $elementlist );
|
332 |
+
|
333 |
+
}
|
334 |
+
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Export Date Options
|
338 |
+
*
|
339 |
+
* @since 0.9.6
|
340 |
+
* @global type $wpdb
|
341 |
+
* @return Array of objects
|
342 |
+
*/
|
343 |
+
public static function get_user_registered_dates()
|
344 |
+
{
|
345 |
+
|
346 |
+
// invite in global objects ##
|
347 |
+
global $wpdb;
|
348 |
+
|
349 |
+
// query user table for oldest and newest registration ##
|
350 |
+
$range =
|
351 |
+
$wpdb->get_results (
|
352 |
+
#$wpdb->prepare (
|
353 |
+
"
|
354 |
+
SELECT
|
355 |
+
MIN( user_registered ) AS first,
|
356 |
+
MAX( user_registered ) AS last
|
357 |
+
FROM
|
358 |
+
{$wpdb->users}
|
359 |
+
"
|
360 |
+
#)
|
361 |
+
);
|
362 |
+
|
363 |
+
return $range;
|
364 |
+
|
365 |
+
}
|
366 |
+
|
367 |
+
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Sanitize data
|
371 |
+
*
|
372 |
+
* @since 1.2.8
|
373 |
+
* @return string
|
374 |
+
*/
|
375 |
+
public static function sanitize( $value )
|
376 |
+
{
|
377 |
+
|
378 |
+
// emove line breaks ##
|
379 |
+
$value = str_replace("\r", '', $value);
|
380 |
+
$value = str_replace("\n", '', $value);
|
381 |
+
$value = str_replace("\t", '', $value);
|
382 |
+
|
383 |
+
// with wp_kses ##
|
384 |
+
$value = \wp_kses( $value, self::get_allowed_tags() );
|
385 |
+
|
386 |
+
// with esc_html
|
387 |
+
$value = \esc_html( $value );
|
388 |
+
|
389 |
+
// return value ##
|
390 |
+
return $value;
|
391 |
+
|
392 |
+
}
|
393 |
+
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Get allowed tags for wp_kses
|
397 |
+
*
|
398 |
+
* @since 1.2.8
|
399 |
+
* @return Array
|
400 |
+
*/
|
401 |
+
public static function get_allowed_tags()
|
402 |
+
{
|
403 |
+
|
404 |
+
$allowed_tags = array(
|
405 |
+
'a' => array(
|
406 |
+
'href' => array(),
|
407 |
+
'title' => array()
|
408 |
+
),
|
409 |
+
'br' => array(),
|
410 |
+
'em' => array(),
|
411 |
+
'strong' => array(),
|
412 |
+
);
|
413 |
+
|
414 |
+
// kick back via filter ##
|
415 |
+
return \apply_filters( 'q/report/export/allowed_tags', $allowed_tags );
|
416 |
+
|
417 |
+
}
|
418 |
+
|
419 |
+
|
420 |
+
}
|
library/core/export.php
ADDED
@@ -0,0 +1,607 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
use q\report\core\xml as xml;
|
8 |
+
|
9 |
+
// load it up ##
|
10 |
+
\q\report\core\export::run();
|
11 |
+
|
12 |
+
class export extends \q_report {
|
13 |
+
|
14 |
+
public static function run()
|
15 |
+
{
|
16 |
+
|
17 |
+
if ( \is_admin() ) {
|
18 |
+
|
19 |
+
// run export ##
|
20 |
+
\add_action( 'admin_init', array( get_class(), 'render' ), 1000003 );
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Attempt to generate the export file based on the passed arguements
|
29 |
+
*
|
30 |
+
* @since 0.1
|
31 |
+
* @return Mixes
|
32 |
+
**/
|
33 |
+
public static function render()
|
34 |
+
{
|
35 |
+
|
36 |
+
// Check if the user clicked on the Save, Load, or Delete Settings buttons ##
|
37 |
+
if (
|
38 |
+
! isset( $_POST['_wpnonce-q-report-admin-page'] )
|
39 |
+
|| isset( $_POST['load_export'] )
|
40 |
+
|| isset( $_POST['save_export'] )
|
41 |
+
|| isset( $_POST['delete_export'] ) )
|
42 |
+
{
|
43 |
+
|
44 |
+
return false;
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
// Increase maximum execution time to prevent "Maximum execution time exceeded" error ##
|
49 |
+
ini_set( 'max_execution_time', -1 );
|
50 |
+
ini_set( 'memory_limit', -1 ); // bad idea? ##
|
51 |
+
|
52 |
+
// check admin referer ##
|
53 |
+
\check_admin_referer( 'q-report-admin-page', '_wpnonce-q-report-admin-page' );
|
54 |
+
|
55 |
+
// build argument array ##
|
56 |
+
$args = array(
|
57 |
+
'fields' => ( isset( $_POST['user_fields'] ) && '1' == $_POST['user_fields'] ) ?
|
58 |
+
'all' :
|
59 |
+
array( 'ID' ), // exclude standard wp_users fields from get_users query ##
|
60 |
+
'role' => \sanitize_text_field( $_POST['role'] )
|
61 |
+
);
|
62 |
+
|
63 |
+
// is there a range limit in place for the export ? ##
|
64 |
+
if ( isset( $_POST['limit_total'] ) && '' != $_POST['limit_total'] ) {
|
65 |
+
|
66 |
+
// let's just make sure they are integer values ##
|
67 |
+
$limit_offset = isset( $_POST['limit_offset'] ) ? (int)$_POST['limit_offset'] : 0 ;
|
68 |
+
$limit_total = (int)$_POST['limit_total'];
|
69 |
+
|
70 |
+
if ( is_int( $limit_offset ) && is_int( $limit_total ) ) { // confirm we have integer values ##
|
71 |
+
|
72 |
+
$args['offset'] = $limit_offset;
|
73 |
+
$args['number'] = $limit_total; // number - Limit the total number of users returned ##
|
74 |
+
|
75 |
+
// test it ##
|
76 |
+
#if ( self::$debug )helper::log( $args );
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
}
|
81 |
+
|
82 |
+
// add custom args via filters ##
|
83 |
+
$args = \apply_filters( 'q/report/export/args', $args );
|
84 |
+
|
85 |
+
#helper::log( $args );
|
86 |
+
|
87 |
+
// pre_user query ##
|
88 |
+
\add_action( 'pre_user_query', array( get_class(), 'pre_user_query' ) );
|
89 |
+
$users = \get_users( $args );
|
90 |
+
\remove_action( 'pre_user_query', array( get_class(), 'pre_user_query' ) );
|
91 |
+
|
92 |
+
// test args ##
|
93 |
+
#if ( self::$debug ) helper::log ( $users );
|
94 |
+
|
95 |
+
// no users found, so chuck an error into the args array and exit the export ##
|
96 |
+
if ( ! $users ) {
|
97 |
+
|
98 |
+
\wp_redirect( \add_query_arg( 'error', 'empty', \wp_get_referer() ) );
|
99 |
+
exit;
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
// get sitename and clean it up ##
|
104 |
+
$sitename = \sanitize_key( \get_bloginfo( 'name' ) );
|
105 |
+
if ( ! empty( $sitename ) ) {
|
106 |
+
$sitename .= '.';
|
107 |
+
}
|
108 |
+
|
109 |
+
// export method ? ##
|
110 |
+
$export_method = 'excel'; // default to Excel export ##
|
111 |
+
if ( isset( $_POST['format'] ) && $_POST['format'] != '' ) {
|
112 |
+
|
113 |
+
$export_method = \sanitize_text_field( $_POST['format'] );
|
114 |
+
|
115 |
+
}
|
116 |
+
|
117 |
+
// set export filename structure ##
|
118 |
+
$filename = $sitename . 'report.' . date( 'Y-m-d-H-i-s' );
|
119 |
+
|
120 |
+
switch ( $export_method ) {
|
121 |
+
|
122 |
+
case ( 'csv' ):
|
123 |
+
|
124 |
+
// to csv ##
|
125 |
+
header( 'Content-Description: File Transfer' );
|
126 |
+
header( 'Content-Disposition: attachment; filename='.$filename.'.csv' );
|
127 |
+
header( 'Content-Type: text/csv; charset=' . \get_option( 'blog_charset' ), true );
|
128 |
+
|
129 |
+
// set a csv check flag
|
130 |
+
$is_csv = true;
|
131 |
+
|
132 |
+
// nothing here
|
133 |
+
$doc_begin = '';
|
134 |
+
|
135 |
+
//preformat
|
136 |
+
$pre = '';
|
137 |
+
|
138 |
+
// how to seperate data ##
|
139 |
+
$seperator = ','; // comma for csv ##
|
140 |
+
|
141 |
+
// line break ##
|
142 |
+
$breaker = "\n";
|
143 |
+
|
144 |
+
// nothing here
|
145 |
+
$doc_end = '';
|
146 |
+
|
147 |
+
break;
|
148 |
+
|
149 |
+
case ( 'excel' ):
|
150 |
+
|
151 |
+
// to xls ##
|
152 |
+
header( 'Content-Description: File Transfer' );
|
153 |
+
header("Content-Type: application/vnd.ms-excel");
|
154 |
+
header("Content-Disposition: attachment; filename=$filename.xls");
|
155 |
+
header("Pragma: no-cache");
|
156 |
+
header("Expires: 0");
|
157 |
+
|
158 |
+
// set a csv check flag
|
159 |
+
$is_csv = false;
|
160 |
+
|
161 |
+
// open xml
|
162 |
+
$doc_begin = xml::begin();
|
163 |
+
|
164 |
+
//preformat
|
165 |
+
$pre = xml::pre();
|
166 |
+
|
167 |
+
// how to seperate data ##
|
168 |
+
$seperator = xml::seperator();
|
169 |
+
|
170 |
+
// line break ##
|
171 |
+
$breaker = xml::breaker();
|
172 |
+
|
173 |
+
// close xml
|
174 |
+
$doc_end = xml::end();
|
175 |
+
|
176 |
+
break;
|
177 |
+
|
178 |
+
}
|
179 |
+
|
180 |
+
|
181 |
+
// check for selected usermeta fields ##
|
182 |
+
$usermeta = isset( $_POST['usermeta'] ) ? $_POST['usermeta']: '';
|
183 |
+
#helper::log( $usermeta );
|
184 |
+
$usermeta_fields = array();
|
185 |
+
|
186 |
+
// loop over each field and sanitize ##
|
187 |
+
if ( $usermeta && is_array( $usermeta ) ) {
|
188 |
+
foreach( $usermeta as $field ) {
|
189 |
+
$usermeta_fields[] = \sanitize_text_field ( $field );
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
#helper::log( $usermeta_fields );
|
194 |
+
#exit;
|
195 |
+
|
196 |
+
// check for selected x profile fields ##
|
197 |
+
$bp_fields = isset( $_POST['bp_fields'] ) ? $_POST['bp_fields'] : '';
|
198 |
+
$bp_fields_passed = array();
|
199 |
+
if ( $bp_fields && is_array( $bp_fields ) ) {
|
200 |
+
|
201 |
+
foreach( $bp_fields as $field ) {
|
202 |
+
|
203 |
+
// reverse tidy ##
|
204 |
+
$field = str_replace( '__', ' ', \sanitize_text_field ( $field ) );
|
205 |
+
|
206 |
+
// add to array ##
|
207 |
+
$bp_fields_passed[] = $field;
|
208 |
+
|
209 |
+
}
|
210 |
+
|
211 |
+
}
|
212 |
+
|
213 |
+
// cwjordan: check for x profile fields we want update time for ##
|
214 |
+
$bp_fields_update = isset( $_POST['bp_fields_update_time'] ) ? $_POST['bp_fields_update_time'] : '';
|
215 |
+
$bp_fields_update_passed = array();
|
216 |
+
if ( $bp_fields_update && is_array( $bp_fields_update ) ) {
|
217 |
+
|
218 |
+
foreach( $bp_fields_update as $field ) {
|
219 |
+
|
220 |
+
// reverse tidy ##
|
221 |
+
$field = str_replace( '__', ' ', \sanitize_text_field ( $field ) );
|
222 |
+
|
223 |
+
// add to array ##
|
224 |
+
$bp_fields_update_passed[] = $field . " Update Date";
|
225 |
+
|
226 |
+
}
|
227 |
+
|
228 |
+
}
|
229 |
+
|
230 |
+
// global wpdb object ##
|
231 |
+
global $wpdb;
|
232 |
+
|
233 |
+
// debug ##
|
234 |
+
#helper::log( 'merging array' );
|
235 |
+
|
236 |
+
// compile final fields list ##
|
237 |
+
$fields = array_merge(
|
238 |
+
core::get_user_fields() // standard wp_user fields ##
|
239 |
+
, core::get_special_fields() // 'special' fields - which are controlled via dedicated checks ##
|
240 |
+
, $usermeta_fields // wp_user_meta fields ##
|
241 |
+
, $bp_fields_passed // selected buddypress fields ##
|
242 |
+
, $bp_fields_update_passed // update date for buddypress fields ##
|
243 |
+
);
|
244 |
+
|
245 |
+
// test field array ##
|
246 |
+
#helper::log( $fields );
|
247 |
+
|
248 |
+
// build the document headers ##
|
249 |
+
$headers = array();
|
250 |
+
|
251 |
+
foreach ( $fields as $key => $field ) {
|
252 |
+
|
253 |
+
#helper::log( 'Field: '. $field );
|
254 |
+
|
255 |
+
// filter field name ##
|
256 |
+
$field = \apply_filters( 'q/report/export/field', $field );
|
257 |
+
|
258 |
+
// grab fields to exclude from exports - filterable ##
|
259 |
+
if ( in_array( $fields[$key], core::get_exclude_fields() ) ) {
|
260 |
+
|
261 |
+
#helper::log( 'Dump Field: '. $fields[$key] );
|
262 |
+
|
263 |
+
// ditch 'em ##
|
264 |
+
unset( $fields[$key] );
|
265 |
+
|
266 |
+
} else {
|
267 |
+
|
268 |
+
if ( $is_csv ) {
|
269 |
+
|
270 |
+
$headers[] = '"' . $field . '"';
|
271 |
+
|
272 |
+
} else {
|
273 |
+
|
274 |
+
$headers[] = $field;
|
275 |
+
|
276 |
+
}
|
277 |
+
|
278 |
+
}
|
279 |
+
|
280 |
+
}
|
281 |
+
|
282 |
+
// quick check ##
|
283 |
+
#helper::log( $fields );
|
284 |
+
#if ( self::$debug ) #helper::log( $bp_fields_passed );
|
285 |
+
|
286 |
+
// no more buffering while spitting back the export data ##
|
287 |
+
if( ob_get_level() > 0 ) ob_end_flush();
|
288 |
+
|
289 |
+
// get the value in bytes allocated for Memory via php.ini ##
|
290 |
+
// @link http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue
|
291 |
+
$memory_limit = core::return_bytes( ini_get('memory_limit') ) * .75;
|
292 |
+
|
293 |
+
// we need to disable caching while exporting because we export so much data that it could blow the memory cache
|
294 |
+
// if we can't override the cache here, we'll have to clear it later...
|
295 |
+
if ( function_exists( 'override_function' ) ) {
|
296 |
+
|
297 |
+
override_function('wp_cache_add', '$key, $data, $group="", $expire=0', '');
|
298 |
+
override_function('wp_cache_set', '$key, $data, $group="", $expire=0', '');
|
299 |
+
override_function('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
|
300 |
+
override_function('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
|
301 |
+
|
302 |
+
} elseif ( function_exists( 'runkit_function_redefine' ) ) {
|
303 |
+
|
304 |
+
runkit_function_redefine('wp_cache_add', '$key, $data, $group="", $expire=0', '');
|
305 |
+
runkit_function_redefine('wp_cache_set', '$key, $data, $group="", $expire=0', '');
|
306 |
+
runkit_function_redefine('wp_cache_replace', '$key, $data, $group="", $expire=0', '');
|
307 |
+
runkit_function_redefine('wp_cache_add_non_persistent_groups', '$key, $data, $group="", $expire=0', '');
|
308 |
+
|
309 |
+
}
|
310 |
+
|
311 |
+
// open doc wrapper.. ##
|
312 |
+
echo $doc_begin;
|
313 |
+
|
314 |
+
// echo headers ##
|
315 |
+
echo $pre . implode( $seperator, $headers ) . $breaker;
|
316 |
+
|
317 |
+
#helper::log( $users );
|
318 |
+
|
319 |
+
// build row values for each user ##
|
320 |
+
foreach ( $users as $user ) {
|
321 |
+
|
322 |
+
#helper::log( $user );
|
323 |
+
|
324 |
+
// check if we're hitting any Memory limits, if so flush them out ##
|
325 |
+
// per http://wordpress.org/support/topic/how-to-exporting-a-lot-of-data-out-of-memory-issue?replies=2
|
326 |
+
if ( memory_get_usage( true ) > $memory_limit ) {
|
327 |
+
\wp_cache_flush();
|
328 |
+
}
|
329 |
+
|
330 |
+
// open up a new empty array ##
|
331 |
+
$data = array();
|
332 |
+
|
333 |
+
// BP loaded ? ##
|
334 |
+
if (
|
335 |
+
! self::$bp_data_available
|
336 |
+
&& function_exists ( 'bp_is_active' )
|
337 |
+
&& \bp_is_active( 'xprofile' )
|
338 |
+
&& class_exists( 'BP_XProfile_ProfileData' )
|
339 |
+
&& method_exists( 'BP_XProfile_ProfileData', 'get_all_for_user' )
|
340 |
+
&& is_callable ( array( 'BP_XProfile_ProfileData', 'get_all_for_user' ) )
|
341 |
+
) {
|
342 |
+
|
343 |
+
helper::log( 'XProfile Accessible' );
|
344 |
+
self::$bp_data_available = true; // we only need to check for BP once ##
|
345 |
+
|
346 |
+
}
|
347 |
+
|
348 |
+
// grab all user data ##
|
349 |
+
if (
|
350 |
+
self::$bp_data_available
|
351 |
+
&& ! $bp_data = \BP_XProfile_ProfileData::get_all_for_user( $user->ID )
|
352 |
+
) {
|
353 |
+
|
354 |
+
// null the data to be sure ##
|
355 |
+
$bp_data = false;
|
356 |
+
|
357 |
+
helper::log( 'XProfile returned no data ID#: '.$user->ID );
|
358 |
+
|
359 |
+
}
|
360 |
+
|
361 |
+
// single query method - get all user_meta data ##
|
362 |
+
$get_user_meta = (array)\get_user_meta( $user->ID );
|
363 |
+
#helper::log( $get_user_meta );
|
364 |
+
|
365 |
+
// loop over each field ##
|
366 |
+
foreach ( $fields as $field ) {
|
367 |
+
|
368 |
+
// check if this is a BP field ##
|
369 |
+
if (
|
370 |
+
isset( $bp_data )
|
371 |
+
&& isset( $bp_data[$field] )
|
372 |
+
&& in_array( $field, $bp_fields_passed )
|
373 |
+
){
|
374 |
+
|
375 |
+
// old way from single BP query ##
|
376 |
+
$value = $bp_data[$field];
|
377 |
+
|
378 |
+
if ( is_array( $value ) ) {
|
379 |
+
|
380 |
+
$value = \maybe_unserialize( $value['field_data'] ); // suggested by @grexican ##
|
381 |
+
#$value = $value['field_data'];
|
382 |
+
|
383 |
+
/**
|
384 |
+
* cwjordan
|
385 |
+
* after unserializing it we then
|
386 |
+
* need to implode it so
|
387 |
+
* that we have something readable?
|
388 |
+
* Going to use :: as a separator
|
389 |
+
* because that's what Buddypress Members Import
|
390 |
+
* expects, but we might want to make that
|
391 |
+
* configurable.
|
392 |
+
*/
|
393 |
+
if ( is_array( $value ) ) {
|
394 |
+
$value = implode( "::", $value );
|
395 |
+
}
|
396 |
+
|
397 |
+
}
|
398 |
+
|
399 |
+
// sanitize ##
|
400 |
+
#$value = $this->sanitize($value);
|
401 |
+
|
402 |
+
// check if this is a BP field we want the updated date for ##
|
403 |
+
}
|
404 |
+
elseif ( in_array( $field, $bp_fields_update_passed ) )
|
405 |
+
{
|
406 |
+
|
407 |
+
global $bp;
|
408 |
+
|
409 |
+
$real_field = str_replace(" Update Date", "", $field);
|
410 |
+
$field_id = \xprofile_get_field_id_from_name( $real_field );
|
411 |
+
$value = $wpdb->get_var (
|
412 |
+
$wpdb->prepare(
|
413 |
+
"
|
414 |
+
SELECT last_updated
|
415 |
+
FROM {$bp->profile->table_name_data}
|
416 |
+
WHERE user_id = %d AND field_id = %d
|
417 |
+
"
|
418 |
+
, $user->ID
|
419 |
+
, $field_id
|
420 |
+
)
|
421 |
+
);
|
422 |
+
|
423 |
+
// include the user's role in the export ##
|
424 |
+
}
|
425 |
+
elseif ( isset( $_POST['roles'] ) && '1' == $_POST['roles'] && $field == 'roles' )
|
426 |
+
{
|
427 |
+
|
428 |
+
// add "Role" as $value ##
|
429 |
+
$value = isset( $user->roles[0] ) ? implode( $user->roles, '|' ) : '' ; // empty value if no role found - or flat array of user roles ##
|
430 |
+
|
431 |
+
// include the user's BP group in the export ##
|
432 |
+
}
|
433 |
+
elseif ( isset( $_POST['groups'] ) && '1' == $_POST['groups'] && $field == 'groups' )
|
434 |
+
{
|
435 |
+
|
436 |
+
if ( function_exists( 'groups_get_user_groups' ) ) {
|
437 |
+
|
438 |
+
// check if user is a member of any groups ##
|
439 |
+
$group_ids = \groups_get_user_groups( $user->ID );
|
440 |
+
|
441 |
+
#$this->pr( $group_ids );
|
442 |
+
#wp_die( pr( 'loaded group data.' ));
|
443 |
+
|
444 |
+
if ( ! $group_ids || $group_ids == '' ) {
|
445 |
+
|
446 |
+
$value = '';
|
447 |
+
|
448 |
+
} else {
|
449 |
+
|
450 |
+
// new empty array ##
|
451 |
+
$groups = array();
|
452 |
+
|
453 |
+
// loop over all groups ##
|
454 |
+
foreach( $group_ids["groups"] as $group_id ) {
|
455 |
+
|
456 |
+
$groups[] = \groups_get_group( array( 'group_id' => $group_id )) -> name . ( end( $group_ids["groups"] ) == $group_id ? '' : '' );
|
457 |
+
|
458 |
+
}
|
459 |
+
|
460 |
+
// implode it ##
|
461 |
+
$value = implode( $groups, '|' );
|
462 |
+
|
463 |
+
}
|
464 |
+
|
465 |
+
} else {
|
466 |
+
|
467 |
+
$value = '';
|
468 |
+
|
469 |
+
}
|
470 |
+
|
471 |
+
}
|
472 |
+
elseif ( $field == 'bp_latest_update' || $field == 'last_activity' )
|
473 |
+
{
|
474 |
+
|
475 |
+
// https://bpdevel.wordpress.com/2014/02/21/user-last_activity-data-and-buddypress-2-0/ ##
|
476 |
+
$value = \bp_get_user_last_activity( $user->ID );
|
477 |
+
|
478 |
+
// user or usermeta field ##
|
479 |
+
}
|
480 |
+
else
|
481 |
+
{
|
482 |
+
|
483 |
+
// the user_meta key isset ##
|
484 |
+
if ( isset( $get_user_meta[$field] ) ) {
|
485 |
+
|
486 |
+
// take from the bulk get_user_meta call - this returns an array in all cases, so we take the first key ##
|
487 |
+
$value = $get_user_meta[$field][0];
|
488 |
+
|
489 |
+
// standard WP_User value ##
|
490 |
+
} else {
|
491 |
+
|
492 |
+
// use the magically assigned value from WP_Users
|
493 |
+
$value = isset( $user->{$field} ) ? $user->{$field} : null ;
|
494 |
+
|
495 |
+
}
|
496 |
+
|
497 |
+
|
498 |
+
// the $value might be serialized ##
|
499 |
+
$value = core::unserialize( $value );
|
500 |
+
|
501 |
+
// the value is an array ##
|
502 |
+
if ( is_array ( $value ) ) {
|
503 |
+
|
504 |
+
// recursive implode it ##
|
505 |
+
$value = core::recursive_implode( $value );
|
506 |
+
|
507 |
+
}
|
508 |
+
|
509 |
+
// sanitize ##
|
510 |
+
#$value = $this->sanitize($value);
|
511 |
+
|
512 |
+
}
|
513 |
+
|
514 |
+
// filter $value ##
|
515 |
+
$value = \apply_filters( 'q/report/export/value', $value, $field );
|
516 |
+
|
517 |
+
// sanitize ##
|
518 |
+
$value = core::sanitize( $value );
|
519 |
+
|
520 |
+
// wrap values in quotes and add to array ##
|
521 |
+
if ( $is_csv ) {
|
522 |
+
|
523 |
+
$data[] = '"' . str_replace( '"', '""', core::format_value( $value ) ) . '"';
|
524 |
+
|
525 |
+
// just add to array ##
|
526 |
+
} else {
|
527 |
+
|
528 |
+
$data[] = core::format_value( $value );
|
529 |
+
}
|
530 |
+
|
531 |
+
}
|
532 |
+
|
533 |
+
// echo row data ##
|
534 |
+
echo $pre . implode( $seperator, $data ) . $breaker;
|
535 |
+
|
536 |
+
}
|
537 |
+
|
538 |
+
// close doc wrapper..
|
539 |
+
echo $doc_end;
|
540 |
+
|
541 |
+
// stop PHP, so file can export correctly ##
|
542 |
+
exit;
|
543 |
+
|
544 |
+
}
|
545 |
+
|
546 |
+
|
547 |
+
|
548 |
+
|
549 |
+
/**
|
550 |
+
* Pre User Query
|
551 |
+
*
|
552 |
+
* @since 2.0.0
|
553 |
+
*/
|
554 |
+
public static function pre_user_query( $user_search = null )
|
555 |
+
{
|
556 |
+
|
557 |
+
global $wpdb;
|
558 |
+
|
559 |
+
$where = '';
|
560 |
+
|
561 |
+
if ( ! empty( $_POST['start_date'] ) ) {
|
562 |
+
|
563 |
+
$date = new \DateTime( \sanitize_text_field ( $_POST['start_date'] ). ' 00:00:00' );
|
564 |
+
$date_formatted = $date->format( 'Y-m-d H:i:s' );
|
565 |
+
|
566 |
+
$where .= $wpdb->prepare( " AND $wpdb->users.user_registered >= %s", $date_formatted );
|
567 |
+
|
568 |
+
}
|
569 |
+
if ( ! empty( $_POST['end_date'] ) ) {
|
570 |
+
|
571 |
+
$date = new \DateTime( \sanitize_text_field ( $_POST['end_date'] ). ' 00:00:00' );
|
572 |
+
$date_formatted = $date->format( 'Y-m-d H:i:s' );
|
573 |
+
|
574 |
+
$where .= $wpdb->prepare( " AND $wpdb->users.user_registered < %s", $date_formatted );
|
575 |
+
|
576 |
+
}
|
577 |
+
|
578 |
+
// search by last update time of BP extended fields ##
|
579 |
+
if (
|
580 |
+
class_exists( 'BP_Xprofile_Field' )
|
581 |
+
&& ( isset ($_POST['updated_since_date'] ) && $_POST['updated_since_date'] != '' )
|
582 |
+
&& (isset ($_POST['bp_field_updated_since'] ) && $_POST['bp_field_updated_since'] != '' )
|
583 |
+
) {
|
584 |
+
|
585 |
+
$last_updated_date = new \DateTime( \sanitize_text_field ( $_POST['updated_since_date'] ) . ' 00:00:00' );
|
586 |
+
self::$updated_since_date = $last_updated_date->format( 'Y-m-d H:i:s' );
|
587 |
+
self::$field_updated_since = \sanitize_text_field ( $_POST['bp_field_updated_since'] );
|
588 |
+
$field_updated_since_id = \BP_Xprofile_Field::get_id_from_name( self::$field_updated_since );
|
589 |
+
$user_search->query_from .= " JOIN `wp_bp_xprofile_data` XP ON XP.user_id = wp_users.ID ";
|
590 |
+
$where .= $wpdb->prepare( " AND XP.field_id = %s AND XP.last_updated >= %s", $field_updated_since_id, self::$updated_since_date );
|
591 |
+
|
592 |
+
}
|
593 |
+
|
594 |
+
if ( ! empty( $where ) ) {
|
595 |
+
|
596 |
+
$user_search->query_where = str_replace( 'WHERE 1=1', "WHERE 1=1 $where", $user_search->query_where );
|
597 |
+
|
598 |
+
}
|
599 |
+
|
600 |
+
#wp_die( self::$pr( $user_search ) );
|
601 |
+
return $user_search;
|
602 |
+
|
603 |
+
}
|
604 |
+
|
605 |
+
|
606 |
+
|
607 |
+
}
|
library/core/filters.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
\q\report\core\filters::run();
|
10 |
+
|
11 |
+
class filters extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// EUD - filter key shown ##
|
19 |
+
\add_filter( 'q/report/admin/display_key', [ get_class(), 'display_key' ], 1, 1 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Filter keys in EUD plugin
|
28 |
+
*
|
29 |
+
* @since 2.0.0
|
30 |
+
*/
|
31 |
+
public static function display_key( $string = null )
|
32 |
+
{
|
33 |
+
|
34 |
+
#helper::log( 'string from filter: '.$string );
|
35 |
+
|
36 |
+
if ( is_null( $string ) ) {
|
37 |
+
|
38 |
+
return false;
|
39 |
+
|
40 |
+
}
|
41 |
+
|
42 |
+
// array of translations ##
|
43 |
+
$array = [
|
44 |
+
'first_name' => 'First Name',
|
45 |
+
];
|
46 |
+
|
47 |
+
// check if $string exists as key in $array and if so, replace and return ##
|
48 |
+
if ( array_key_exists( $string, $array ) ) {
|
49 |
+
|
50 |
+
return $array[$string];
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
// kick it back ##
|
55 |
+
return $string;
|
56 |
+
|
57 |
+
}
|
58 |
+
|
59 |
+
}
|
library/core/helper.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// namespace ##
|
4 |
+
namespace q\report\core;
|
5 |
+
|
6 |
+
// piggyback Q helper ##
|
7 |
+
use q\core\helper as q_helper;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* helper Class
|
11 |
+
* @package q_report\core
|
12 |
+
*/
|
13 |
+
class helper extends \q_report {
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Write to WP Error Log
|
18 |
+
*
|
19 |
+
* @since 1.5.0
|
20 |
+
* @return void
|
21 |
+
*/
|
22 |
+
public static function log( $log )
|
23 |
+
{
|
24 |
+
|
25 |
+
if ( true === WP_DEBUG ) {
|
26 |
+
|
27 |
+
$trace = debug_backtrace();
|
28 |
+
$caller = $trace[1];
|
29 |
+
|
30 |
+
$suffix = sprintf(
|
31 |
+
__( ' - %s%s() %s:%d', 'Q' )
|
32 |
+
, isset($caller['class']) ? $caller['class'].'::' : ''
|
33 |
+
, $caller['function']
|
34 |
+
, isset( $caller['file'] ) ? $caller['file'] : 'n'
|
35 |
+
, isset( $caller['line'] ) ? $caller['line'] : 'x'
|
36 |
+
);
|
37 |
+
|
38 |
+
if ( is_array( $log ) || is_object( $log ) ) {
|
39 |
+
error_log( print_r( $log, true ).$suffix );
|
40 |
+
} else {
|
41 |
+
error_log( $log.$suffix );
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
}
|
library/core/user.php
ADDED
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
// load it up ##
|
9 |
+
\q\report\core\user::run();
|
10 |
+
|
11 |
+
class user extends \q_report {
|
12 |
+
|
13 |
+
public static function run()
|
14 |
+
{
|
15 |
+
|
16 |
+
if ( \is_admin() ) {
|
17 |
+
|
18 |
+
// load user options ##
|
19 |
+
\add_action( 'admin_init', array( get_class(), 'load' ), 1000002 );
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Load up saved exports for this user
|
28 |
+
* Set to public as hooked into action
|
29 |
+
*
|
30 |
+
* @since 0.9.6
|
31 |
+
* @return Array of saved exports
|
32 |
+
*/
|
33 |
+
public static function load()
|
34 |
+
{
|
35 |
+
|
36 |
+
return self::$q_report_exports =
|
37 |
+
\get_user_meta( \get_current_user_id(), 'q_report_exports' ) ?
|
38 |
+
\get_user_meta( \get_current_user_id(), 'q_report_exports', true ) :
|
39 |
+
array() ;
|
40 |
+
|
41 |
+
#self::log( $this->q_report_exports );
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Get list of saved exports for this user
|
49 |
+
*
|
50 |
+
* @since 0.9.4
|
51 |
+
* @return Array of saved exports
|
52 |
+
*/
|
53 |
+
public static function get_user_options()
|
54 |
+
{
|
55 |
+
|
56 |
+
// get the stored options - filter empty array items ##
|
57 |
+
$q_report_exports = array_filter( self::$q_report_exports );
|
58 |
+
|
59 |
+
// quick check if the array is empty ##
|
60 |
+
if ( empty ( $q_report_exports ) ) {
|
61 |
+
|
62 |
+
return false;
|
63 |
+
|
64 |
+
}
|
65 |
+
|
66 |
+
// test the array of saved exports ##
|
67 |
+
#$this->pr( $q_report_exports );
|
68 |
+
|
69 |
+
// start with an empty array ##
|
70 |
+
$exports = array();
|
71 |
+
|
72 |
+
// loop over each saved export and grab each key ##
|
73 |
+
foreach ( $q_report_exports as $key => $value ) {
|
74 |
+
|
75 |
+
$exports[] = $key;
|
76 |
+
|
77 |
+
}
|
78 |
+
|
79 |
+
// kick back array ##
|
80 |
+
return $exports;
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Check for and load stored user options
|
87 |
+
*
|
88 |
+
* @since 0.9.3
|
89 |
+
* @return void
|
90 |
+
*/
|
91 |
+
public static function get_user_options_by_export( $export = null )
|
92 |
+
{
|
93 |
+
|
94 |
+
// sanity check ##
|
95 |
+
if ( is_null ( $export ) ) { return false; }
|
96 |
+
|
97 |
+
if ( isset( self::$q_report_exports[$export] ) ) {
|
98 |
+
|
99 |
+
self::$usermeta_saved_fields = self::$q_report_exports[$export]['usermeta_saved_fields'];
|
100 |
+
self::$bp_fields_saved_fields = self::$q_report_exports[$export]['bp_fields_saved_fields'];
|
101 |
+
self::$bp_fields_update_time_saved_fields = self::$q_report_exports[$export]['bp_fields_update_time_saved_fields'];
|
102 |
+
self::$updated_since_date = isset( self::$q_report_exports[$export]['updated_since_date'] ) ? self::$q_report_exports[$export]['updated_since_date'] : null ;
|
103 |
+
self::$field_updated_since = isset( self::$q_report_exports[$export]['field_updated_since'] ) ? self::$q_report_exports[$export]['field_updated_since'] : null ;
|
104 |
+
self::$role = self::$q_report_exports[$export]['role'];
|
105 |
+
self::$roles = self::$q_report_exports[$export]['roles'];
|
106 |
+
self::$groups = self::$q_report_exports[$export]['groups'];
|
107 |
+
self::$user_fields = isset( self::$q_report_exports[$export]['user_fields'] ) ? self::$q_report_exports[$export]['user_fields'] : null ;
|
108 |
+
self::$start_date = self::$q_report_exports[$export]['start_date'];
|
109 |
+
self::$end_date = self::$q_report_exports[$export]['end_date'];
|
110 |
+
self::$limit_offset = self::$q_report_exports[$export]['limit_offset'];
|
111 |
+
self::$limit_total = self::$q_report_exports[$export]['limit_total'];
|
112 |
+
self::$format = self::$q_report_exports[$export]['format'];
|
113 |
+
|
114 |
+
} else {
|
115 |
+
|
116 |
+
self::$usermeta_saved_fields = array();
|
117 |
+
self::$bp_fields_saved_fields = array();
|
118 |
+
self::$bp_fields_update_time_saved_fields = array();
|
119 |
+
self::$updated_since_date = '';
|
120 |
+
self::$field_updated_since = '';
|
121 |
+
self::$role = '';
|
122 |
+
self::$user_fields = '1';
|
123 |
+
self::$roles = '1';
|
124 |
+
self::$groups = '1';
|
125 |
+
self::$start_date = '';
|
126 |
+
self::$end_date = '';
|
127 |
+
self::$limit_offset = '';
|
128 |
+
self::$limit_total = '';
|
129 |
+
self::$format = '';
|
130 |
+
|
131 |
+
}
|
132 |
+
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Method to store user options
|
138 |
+
*
|
139 |
+
* @param string $save_export Export Key name
|
140 |
+
* @param array $save_options Array of export options to save
|
141 |
+
* @since 0.9.3
|
142 |
+
* @return void
|
143 |
+
*/
|
144 |
+
public static function set_user_options( $key = null, $options = null )
|
145 |
+
{
|
146 |
+
|
147 |
+
// sanity check ##
|
148 |
+
if ( is_null ( $key ) || is_null ( $options ) ) {
|
149 |
+
|
150 |
+
#$this->pr( 'missing save values' );
|
151 |
+
return false;
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
#$this->pr( $key );
|
156 |
+
#$this->pr( $options );
|
157 |
+
|
158 |
+
// for now, I'm simply allowing keys to be resaved - but this is not so logical ##
|
159 |
+
if ( array_key_exists( $key, self::$q_report_exports ) ) {
|
160 |
+
|
161 |
+
#$this->pr( 'key exists, skipping save' );
|
162 |
+
#return false;
|
163 |
+
|
164 |
+
}
|
165 |
+
|
166 |
+
if ( isset( $options ) && is_array( $options ) ) {
|
167 |
+
|
168 |
+
// update_option sanitizes the option name but not the option value ##
|
169 |
+
foreach ( $options as $field_name => $field_value ) {
|
170 |
+
|
171 |
+
// so do that here. ##
|
172 |
+
if ( is_array( $field_value ) ) {
|
173 |
+
|
174 |
+
foreach ( $field_value as $field_array_key => $field_array_value ) {
|
175 |
+
|
176 |
+
$options[$field_name][$field_array_key] = \sanitize_text_field( $field_array_value );
|
177 |
+
|
178 |
+
}
|
179 |
+
|
180 |
+
} else {
|
181 |
+
|
182 |
+
$options[$field_name] = \sanitize_text_field( $field_value );
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
}
|
187 |
+
|
188 |
+
// assign the sanitized array of values to the class property $q_report_exports as a new array with key $key ##
|
189 |
+
self::$q_report_exports[$key] = $options;
|
190 |
+
|
191 |
+
// update stored user_meta values, if previous key found ##
|
192 |
+
if ( \get_user_meta( \get_current_user_id(), 'q_report_exports' ) !== false ) {
|
193 |
+
|
194 |
+
#update_option( 'q_report_exports', $this->q_report_exports );
|
195 |
+
\update_user_meta( \get_current_user_id(), 'q_report_exports', self::$q_report_exports );
|
196 |
+
|
197 |
+
// create new user meta key ##
|
198 |
+
} else {
|
199 |
+
|
200 |
+
#add_option( 'q_report_exports', $this->q_report_exports, $deprecated, $autoload );
|
201 |
+
\add_user_meta( \get_current_user_id(), 'q_report_exports', self::$q_report_exports );
|
202 |
+
|
203 |
+
}
|
204 |
+
|
205 |
+
}
|
206 |
+
|
207 |
+
}
|
208 |
+
|
209 |
+
|
210 |
+
/**
|
211 |
+
* method to delete user options
|
212 |
+
*
|
213 |
+
* @param $key String Key name to drop from property
|
214 |
+
* @since 0.9.3
|
215 |
+
* @return void
|
216 |
+
*/
|
217 |
+
public static function delete_user_options( $key = null )
|
218 |
+
{
|
219 |
+
|
220 |
+
// sanity check ##
|
221 |
+
if ( is_null ( $key ) || ! array_key_exists( $key, self::$q_report_exports ) ) { return false; }
|
222 |
+
|
223 |
+
// clean it up ##
|
224 |
+
$key = \sanitize_text_field( $key );
|
225 |
+
|
226 |
+
// check it out ##
|
227 |
+
#$this->pr( $key );
|
228 |
+
|
229 |
+
// drop the array by it's key name from the class property ##
|
230 |
+
unset( self::$q_report_exports[$key] );
|
231 |
+
|
232 |
+
// update the saved data ##
|
233 |
+
\update_user_meta( \get_current_user_id(), 'q_report_exports', self::$q_report_exports );
|
234 |
+
|
235 |
+
}
|
236 |
+
|
237 |
+
|
238 |
+
|
239 |
+
}
|
library/core/xml.php
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace q\report\core;
|
4 |
+
|
5 |
+
use q\report\core\core as core;
|
6 |
+
use q\report\core\helper as helper;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* XML template for excel file format
|
10 |
+
*
|
11 |
+
* @since 0.7.7
|
12 |
+
**/
|
13 |
+
|
14 |
+
// load it up ##
|
15 |
+
#\q\report\core\core::run();
|
16 |
+
|
17 |
+
class xml extends \q_report {
|
18 |
+
|
19 |
+
public static function begin()
|
20 |
+
{
|
21 |
+
|
22 |
+
/*
|
23 |
+
$xml_string = <<<XML
|
24 |
+
<xml version="1.0">
|
25 |
+
<mso-application progid="Excel.Sheet">
|
26 |
+
<Workbook
|
27 |
+
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
28 |
+
xmlns:o="urn:schemas-microsoft-com:office:office"
|
29 |
+
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
30 |
+
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
31 |
+
xmlns:html="http://www.w3.org/TR/REC-html40">
|
32 |
+
<Worksheet ss:Name="Exported Users">
|
33 |
+
<Table>
|
34 |
+
XML;
|
35 |
+
$xml_object = new \SimpleXMLElement($xml_string);
|
36 |
+
return $xml_object->asXML();
|
37 |
+
#Changed by Benny to PHP XML syntax to clear 500
|
38 |
+
*/
|
39 |
+
$xml_doc_begin =
|
40 |
+
'<?xml version="1.0"?>
|
41 |
+
<?mso-application progid="Excel.Sheet"?>
|
42 |
+
<Workbook
|
43 |
+
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
44 |
+
xmlns:o="urn:schemas-microsoft-com:office:office"
|
45 |
+
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
46 |
+
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
47 |
+
xmlns:html="http://www.w3.org/TR/REC-html40">
|
48 |
+
<Worksheet ss:Name="Exported Users">
|
49 |
+
<Table>';
|
50 |
+
|
51 |
+
return $xml_doc_begin;
|
52 |
+
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
public static function pre()
|
59 |
+
{
|
60 |
+
|
61 |
+
$xml_pre =
|
62 |
+
'<Row>
|
63 |
+
<Cell>
|
64 |
+
<Data ss:Type="String">';
|
65 |
+
|
66 |
+
return $xml_pre;
|
67 |
+
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
public static function seperator()
|
73 |
+
{
|
74 |
+
|
75 |
+
$xml_seperator =
|
76 |
+
'</Data>
|
77 |
+
</Cell>
|
78 |
+
<Cell>
|
79 |
+
<Data ss:Type="String">';
|
80 |
+
|
81 |
+
return $xml_seperator;
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
|
87 |
+
public static function breaker()
|
88 |
+
{
|
89 |
+
|
90 |
+
$xml_breaker =
|
91 |
+
'</Data>
|
92 |
+
</Cell>
|
93 |
+
</Row>';
|
94 |
+
|
95 |
+
return $xml_breaker;
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
public static function end()
|
101 |
+
{
|
102 |
+
|
103 |
+
$xml_doc_end = '
|
104 |
+
</Table>
|
105 |
+
</Worksheet>
|
106 |
+
</Workbook>';
|
107 |
+
|
108 |
+
return $xml_doc_end;
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
}
|
library/languages/default.mo
ADDED
Binary file
|
library/languages/default.po
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Export User Data\n"
|
4 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/export-users-to-csv\n"
|
5 |
+
"POT-Creation-Date: 2014-03-15 09:46-0000\n"
|
6 |
+
"PO-Revision-Date: 2014-03-15 09:46-0000\n"
|
7 |
+
"Last-Translator: Ray <ray@qstudio.us>\n"
|
8 |
+
"Language-Team: Q Studio <team@qstudio.us>\n"
|
9 |
+
"Language: en\n"
|
10 |
+
"MIME-Version: 1.0\n"
|
11 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
12 |
+
"Content-Transfer-Encoding: 8bit\n"
|
13 |
+
"X-Generator: Poedit 1.6.3\n"
|
14 |
+
"X-Poedit-KeywordsList: _;_e;_n;__\n"
|
15 |
+
"X-Poedit-Basepath: .\n"
|
16 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
"X-Poedit-SearchPath-1: ..\n"
|
20 |
+
|
21 |
+
#: ../export-user-data.php:85 ../export-user-data.php:450
|
22 |
+
msgid "Export User Data"
|
23 |
+
msgstr ""
|
24 |
+
|
25 |
+
#: ../export-user-data.php:445
|
26 |
+
msgid "You do not have sufficient permissions to access this page."
|
27 |
+
msgstr ""
|
28 |
+
|
29 |
+
#: ../export-user-data.php:455
|
30 |
+
msgid "No users found."
|
31 |
+
msgstr ""
|
32 |
+
|
33 |
+
#: ../export-user-data.php:511
|
34 |
+
msgid "User Meta Fields"
|
35 |
+
msgstr ""
|
36 |
+
|
37 |
+
#: ../export-user-data.php:513
|
38 |
+
msgid "Filter"
|
39 |
+
msgstr ""
|
40 |
+
|
41 |
+
#: ../export-user-data.php:513
|
42 |
+
msgid "All"
|
43 |
+
msgstr ""
|
44 |
+
|
45 |
+
#: ../export-user-data.php:513
|
46 |
+
msgid "Common"
|
47 |
+
msgstr ""
|
48 |
+
|
49 |
+
#: ../export-user-data.php:564
|
50 |
+
msgid ""
|
51 |
+
"Select the user meta keys to export, use the filters to simplify the list."
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#: ../export-user-data.php:593
|
55 |
+
msgid "BP xProfile Fields"
|
56 |
+
msgstr ""
|
57 |
+
|
58 |
+
#: ../export-user-data.php:614
|
59 |
+
msgid "Select the BuddyPress XProfile keys to export"
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#: ../export-user-data.php:626
|
63 |
+
msgid "BP xProfile Fields Update Time"
|
64 |
+
msgstr ""
|
65 |
+
|
66 |
+
#: ../export-user-data.php:642
|
67 |
+
msgid "Select the BuddyPress XProfile keys updated dates to export"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#: ../export-user-data.php:653
|
71 |
+
msgid "Role"
|
72 |
+
msgstr ""
|
73 |
+
|
74 |
+
#: ../export-user-data.php:658
|
75 |
+
msgid "All Roles"
|
76 |
+
msgstr ""
|
77 |
+
|
78 |
+
#: ../export-user-data.php:668
|
79 |
+
#, php-format
|
80 |
+
msgid ""
|
81 |
+
"Filter the exported users by a WordPress Role. <a href=\"%s\" target=\"_blank"
|
82 |
+
"\">%s</a>"
|
83 |
+
msgstr ""
|
84 |
+
|
85 |
+
#: ../export-user-data.php:682
|
86 |
+
msgid "Programs"
|
87 |
+
msgstr ""
|
88 |
+
|
89 |
+
#: ../export-user-data.php:687
|
90 |
+
msgid "All Programs"
|
91 |
+
msgstr ""
|
92 |
+
|
93 |
+
#: ../export-user-data.php:708
|
94 |
+
msgid "Registered"
|
95 |
+
msgstr ""
|
96 |
+
|
97 |
+
#: ../export-user-data.php:711
|
98 |
+
msgid "Start Date"
|
99 |
+
msgstr ""
|
100 |
+
|
101 |
+
#: ../export-user-data.php:715
|
102 |
+
msgid "End Date"
|
103 |
+
msgstr ""
|
104 |
+
|
105 |
+
#: ../export-user-data.php:720
|
106 |
+
msgid "Pick a start and end user registration date to limit the results."
|
107 |
+
msgstr ""
|
108 |
+
|
109 |
+
#: ../export-user-data.php:727
|
110 |
+
msgid "Limit Range"
|
111 |
+
msgstr ""
|
112 |
+
|
113 |
+
#: ../export-user-data.php:729
|
114 |
+
msgid "Offset"
|
115 |
+
msgstr ""
|
116 |
+
|
117 |
+
#: ../export-user-data.php:730
|
118 |
+
msgid "Total"
|
119 |
+
msgstr ""
|
120 |
+
|
121 |
+
#: ../export-user-data.php:733
|
122 |
+
#, php-format
|
123 |
+
msgid ""
|
124 |
+
"Enter an offset start number and a total number of users to export. <a href="
|
125 |
+
"\"%s\" target=\"_blank\">%s</a>"
|
126 |
+
msgstr ""
|
127 |
+
|
128 |
+
#: ../export-user-data.php:742
|
129 |
+
msgid "Format"
|
130 |
+
msgstr ""
|
131 |
+
|
132 |
+
#: ../export-user-data.php:747
|
133 |
+
msgid "Excel"
|
134 |
+
msgstr ""
|
135 |
+
|
136 |
+
#: ../export-user-data.php:748
|
137 |
+
msgid "CSV"
|
138 |
+
msgstr ""
|
139 |
+
|
140 |
+
#: ../export-user-data.php:754
|
141 |
+
msgid "Select the format for the export file."
|
142 |
+
msgstr ""
|
143 |
+
|
144 |
+
#: ../export-user-data.php:762
|
145 |
+
msgid "Advanced Options"
|
146 |
+
msgstr ""
|
147 |
+
|
148 |
+
#: ../export-user-data.php:766 ../export-user-data.php:840
|
149 |
+
msgid "Show"
|
150 |
+
msgstr ""
|
151 |
+
|
152 |
+
#: ../export-user-data.php:774
|
153 |
+
msgid "Export"
|
154 |
+
msgstr ""
|
155 |
+
|
156 |
+
#: ../export-user-data.php:838
|
157 |
+
msgid "Hide"
|
158 |
+
msgstr ""
|
library/languages/export-user-data-el.mo
ADDED
Binary file
|
library/languages/export-user-data-el.po
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Export User Data\n"
|
4 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/export-users-to-csv\n"
|
5 |
+
"POT-Creation-Date: 2014-03-15 09:46-0000\n"
|
6 |
+
"PO-Revision-Date: 2015-05-26 16:27+0200\n"
|
7 |
+
"Last-Translator: Ray <ray@qstudio.us>\n"
|
8 |
+
"Language-Team: Q Studio <team@qstudio.us>\n"
|
9 |
+
"Language: en\n"
|
10 |
+
"MIME-Version: 1.0\n"
|
11 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
12 |
+
"Content-Transfer-Encoding: 8bit\n"
|
13 |
+
"X-Generator: Poedit 1.7.5\n"
|
14 |
+
"X-Poedit-KeywordsList: _;_e;_n;__\n"
|
15 |
+
"X-Poedit-Basepath: .\n"
|
16 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
"X-Poedit-SearchPath-1: ..\n"
|
20 |
+
|
21 |
+
#: ../export-user-data.php:85 ../export-user-data.php:450
|
22 |
+
msgid "Export User Data"
|
23 |
+
msgstr "Εξαγωγή Δεδομένων Χρήστη"
|
24 |
+
|
25 |
+
#: ../export-user-data.php:445
|
26 |
+
msgid "You do not have sufficient permissions to access this page."
|
27 |
+
msgstr "Δεν έχετε επαρκή δικαιώματα για πρόσβαση στη σελίδα."
|
28 |
+
|
29 |
+
#: ../export-user-data.php:455
|
30 |
+
msgid "No users found."
|
31 |
+
msgstr "Δεν βρέθηκαν χρήστες"
|
32 |
+
|
33 |
+
#: ../export-user-data.php:511
|
34 |
+
msgid "User Meta Fields"
|
35 |
+
msgstr "Meta Πεδία Χρήστη"
|
36 |
+
|
37 |
+
#: ../export-user-data.php:513
|
38 |
+
msgid "Filter"
|
39 |
+
msgstr "Φίλτράρισμα"
|
40 |
+
|
41 |
+
#: ../export-user-data.php:513
|
42 |
+
msgid "All"
|
43 |
+
msgstr "Όλα"
|
44 |
+
|
45 |
+
#: ../export-user-data.php:513
|
46 |
+
msgid "Common"
|
47 |
+
msgstr "Κοινά"
|
48 |
+
|
49 |
+
#: ../export-user-data.php:564
|
50 |
+
msgid ""
|
51 |
+
"Select the user meta keys to export, use the filters to simplify the list."
|
52 |
+
msgstr ""
|
53 |
+
"Επιλέξτε τα meta κλειδιά του χρήστη προς εξαγωγή, χρησιμοποιήστε το "
|
54 |
+
"φιλτράρισμα για να απλοποιήσετε τη λίστα."
|
55 |
+
|
56 |
+
#: ../export-user-data.php:593
|
57 |
+
msgid "BP xProfile Fields"
|
58 |
+
msgstr "BP xProfile Πεδία"
|
59 |
+
|
60 |
+
#: ../export-user-data.php:614
|
61 |
+
msgid "Select the BuddyPress XProfile keys to export"
|
62 |
+
msgstr "Επιλέξτε τα BuddyPress XProfile κλειδιά προς εξαγωγή."
|
63 |
+
|
64 |
+
#: ../export-user-data.php:626
|
65 |
+
msgid "BP xProfile Fields Update Time"
|
66 |
+
msgstr "Ενημέρωση ώρας BP xProfile Πεδίων"
|
67 |
+
|
68 |
+
#: ../export-user-data.php:642
|
69 |
+
msgid "Select the BuddyPress XProfile keys updated dates to export"
|
70 |
+
msgstr ""
|
71 |
+
"Επιλέξτε τις ημερομηνίες ενημέρωσης των BuddyPress XProfile κλειδιών προς "
|
72 |
+
"εξαγωγή."
|
73 |
+
|
74 |
+
#: ../export-user-data.php:653
|
75 |
+
msgid "Role"
|
76 |
+
msgstr "Ρόλοι"
|
77 |
+
|
78 |
+
#: ../export-user-data.php:658
|
79 |
+
msgid "All Roles"
|
80 |
+
msgstr "Όλοι οι Ρόλοι"
|
81 |
+
|
82 |
+
#: ../export-user-data.php:668
|
83 |
+
#, php-format
|
84 |
+
msgid ""
|
85 |
+
"Filter the exported users by a WordPress Role. <a href=\"%s\" target=\"_blank"
|
86 |
+
"\">%s</a>"
|
87 |
+
msgstr ""
|
88 |
+
"Φιλτράρετε τους χρήστες προς εξαγωγή ως προς το Wordpress ρόλο τους. <a href="
|
89 |
+
"\"%s\" target=\"_blank\">%s</a>"
|
90 |
+
|
91 |
+
#: ../export-user-data.php:682
|
92 |
+
msgid "Programs"
|
93 |
+
msgstr "Προγράμματα"
|
94 |
+
|
95 |
+
#: ../export-user-data.php:687
|
96 |
+
msgid "All Programs"
|
97 |
+
msgstr "Όλα τα προγράμματα"
|
98 |
+
|
99 |
+
#: ../export-user-data.php:708
|
100 |
+
msgid "Registered"
|
101 |
+
msgstr "Εγγεγραμμένοι"
|
102 |
+
|
103 |
+
#: ../export-user-data.php:711
|
104 |
+
msgid "Start Date"
|
105 |
+
msgstr "Ημερομηνία Έναρξης"
|
106 |
+
|
107 |
+
#: ../export-user-data.php:715
|
108 |
+
msgid "End Date"
|
109 |
+
msgstr "Ημερομηνία Λήξης"
|
110 |
+
|
111 |
+
#: ../export-user-data.php:720
|
112 |
+
msgid "Pick a start and end user registration date to limit the results."
|
113 |
+
msgstr ""
|
114 |
+
"Επιλέξτε ημερομηνία έναρξης και λήξης για να περιορίσετε τα αποτελέσματα."
|
115 |
+
|
116 |
+
#: ../export-user-data.php:727
|
117 |
+
msgid "Limit Range"
|
118 |
+
msgstr "Εύρος"
|
119 |
+
|
120 |
+
#: ../export-user-data.php:729
|
121 |
+
msgid "Offset"
|
122 |
+
msgstr "Offset"
|
123 |
+
|
124 |
+
#: ../export-user-data.php:730
|
125 |
+
msgid "Total"
|
126 |
+
msgstr "Σύνολο"
|
127 |
+
|
128 |
+
#: ../export-user-data.php:733
|
129 |
+
#, php-format
|
130 |
+
msgid ""
|
131 |
+
"Enter an offset start number and a total number of users to export. <a href="
|
132 |
+
"\"%s\" target=\"_blank\">%s</a>"
|
133 |
+
msgstr ""
|
134 |
+
"Πληκτρολογήστε έναν offset αριθμό έναρξης και το συνολικό αριθμό των χρηστών "
|
135 |
+
"προς εξαγωγή. <a href=\"%s\" target=\"_blank\">%s</a>"
|
136 |
+
|
137 |
+
#: ../export-user-data.php:742
|
138 |
+
msgid "Format"
|
139 |
+
msgstr "Φορμάτ"
|
140 |
+
|
141 |
+
#: ../export-user-data.php:747
|
142 |
+
msgid "Excel"
|
143 |
+
msgstr "Excel"
|
144 |
+
|
145 |
+
#: ../export-user-data.php:748
|
146 |
+
msgid "CSV"
|
147 |
+
msgstr "CSV"
|
148 |
+
|
149 |
+
#: ../export-user-data.php:754
|
150 |
+
msgid "Select the format for the export file."
|
151 |
+
msgstr "Επιλέξτε το format για το αρχείο προς εξαγωγή."
|
152 |
+
|
153 |
+
#: ../export-user-data.php:762
|
154 |
+
msgid "Advanced Options"
|
155 |
+
msgstr "Σύνθετες επιλογές"
|
156 |
+
|
157 |
+
#: ../export-user-data.php:766 ../export-user-data.php:840
|
158 |
+
msgid "Show"
|
159 |
+
msgstr "Προβολή"
|
160 |
+
|
161 |
+
#: ../export-user-data.php:774
|
162 |
+
msgid "Export"
|
163 |
+
msgstr "Εξαγωγή"
|
164 |
+
|
165 |
+
#: ../export-user-data.php:838
|
166 |
+
msgid "Hide"
|
167 |
+
msgstr "Απόκρυψη"
|
library/languages/export-user-data-es_ES.mo
ADDED
Binary file
|
library/languages/export-user-data-es_ES.po
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Export User Data\n"
|
4 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/export-users-to-csv\n"
|
5 |
+
"POT-Creation-Date: 2014-03-15 09:46-0000\n"
|
6 |
+
"PO-Revision-Date: Tue Dec 15 2015 15:03:14 GMT+0100 (Hora estándar romance)\n"
|
7 |
+
"Last-Translator: elias <elias@estudions.es>\n"
|
8 |
+
"Language-Team: Q Studio <team@qstudio.us>\n"
|
9 |
+
"Language: Spanish (Spain)\n"
|
10 |
+
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
11 |
+
"MIME-Version: 1.0\n"
|
12 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
13 |
+
"Content-Transfer-Encoding: 8bit\n"
|
14 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
15 |
+
"X-Generator: Loco - https://localise.biz/\n"
|
16 |
+
"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
|
17 |
+
"__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
|
18 |
+
"_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
|
19 |
+
"esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
|
20 |
+
"esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
|
21 |
+
"X-Poedit-Basepath: .\n"
|
22 |
+
"X-Poedit-SearchPath-0: .\n"
|
23 |
+
"X-Poedit-SearchPath-1: ..\n"
|
24 |
+
"X-Loco-Target-Locale: es_ES"
|
25 |
+
|
26 |
+
#: ../export-user-data.php:626
|
27 |
+
msgid "BP xProfile Fields Update Time"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#: ../export-user-data.php:642
|
31 |
+
msgid "Select the BuddyPress XProfile keys updated dates to export"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#: ../export-user-data.php:682
|
35 |
+
msgid "Programs"
|
36 |
+
msgstr ""
|
37 |
+
|
38 |
+
#: ../export-user-data.php:687
|
39 |
+
msgid "All Programs"
|
40 |
+
msgstr ""
|
41 |
+
|
42 |
+
#: ../export-user-data.php:729
|
43 |
+
msgid "Offset"
|
44 |
+
msgstr ""
|
45 |
+
|
46 |
+
#: ../export-user-data.php:733
|
47 |
+
#, php-format
|
48 |
+
msgid ""
|
49 |
+
"Enter an offset start number and a total number of users to export. <a "
|
50 |
+
"href=\"%s\" target=\"_blank\">%s</a>"
|
51 |
+
msgstr ""
|
52 |
+
|
53 |
+
#: ../export-user-data.php:762
|
54 |
+
msgid "Advanced Options"
|
55 |
+
msgstr "Opciones avanzadas"
|
56 |
+
|
57 |
+
#: ../export-user-data.php:766 ../export-user-data.php:840
|
58 |
+
msgid "Show"
|
59 |
+
msgstr "Mostrar"
|
60 |
+
|
61 |
+
#: ../export-user-data.php:774
|
62 |
+
msgid "Export"
|
63 |
+
msgstr "Exportar"
|
64 |
+
|
65 |
+
#: ../export-user-data.php:838
|
66 |
+
msgid "Hide"
|
67 |
+
msgstr "Ocultar"
|
68 |
+
|
69 |
+
#: ../export-user-data.php:85 ../export-user-data.php:450
|
70 |
+
msgid "Export User Data"
|
71 |
+
msgstr "Exportar datos de Usuarios"
|
72 |
+
|
73 |
+
#: ../export-user-data.php:445
|
74 |
+
msgid "You do not have sufficient permissions to access this page."
|
75 |
+
msgstr "No tienes suficientes permisos para acceder a esta página."
|
76 |
+
|
77 |
+
#: ../export-user-data.php:455
|
78 |
+
msgid "No users found."
|
79 |
+
msgstr "No se han encontrado usuarios"
|
80 |
+
|
81 |
+
#: ../export-user-data.php:511
|
82 |
+
msgid "User Meta Fields"
|
83 |
+
msgstr "Campos 'meta' de los usuarios"
|
84 |
+
|
85 |
+
#: ../export-user-data.php:513
|
86 |
+
msgid "Filter"
|
87 |
+
msgstr "Filtrar"
|
88 |
+
|
89 |
+
#: ../export-user-data.php:513
|
90 |
+
msgid "All"
|
91 |
+
msgstr "Todo"
|
92 |
+
|
93 |
+
#: ../export-user-data.php:513
|
94 |
+
msgid "Common"
|
95 |
+
msgstr "Común"
|
96 |
+
|
97 |
+
#: ../export-user-data.php:564
|
98 |
+
msgid "Select the user meta keys to export, use the filters to simplify the list."
|
99 |
+
msgstr "Elige las claves 'meta' a export, usa el filtro para reducir la lista."
|
100 |
+
|
101 |
+
#: ../export-user-data.php:593
|
102 |
+
msgid "BP xProfile Fields"
|
103 |
+
msgstr "Campos 'xProfile' de BuddyPress"
|
104 |
+
|
105 |
+
#: ../export-user-data.php:614
|
106 |
+
msgid "Select the BuddyPress XProfile keys to export"
|
107 |
+
msgstr "Elige los campos 'xProfile' de BuddyPress a exportar"
|
108 |
+
|
109 |
+
#: ../export-user-data.php:653
|
110 |
+
msgid "Role"
|
111 |
+
msgstr "Rol"
|
112 |
+
|
113 |
+
#: ../export-user-data.php:658
|
114 |
+
msgid "All Roles"
|
115 |
+
msgstr "Todos los Roles"
|
116 |
+
|
117 |
+
#: ../export-user-data.php:668
|
118 |
+
#, php-format
|
119 |
+
msgid ""
|
120 |
+
"Filter the exported users by a WordPress Role. <a href=\"%s\" "
|
121 |
+
"target=\"_blank\">%s</a>"
|
122 |
+
msgstr ""
|
123 |
+
"Filtrar los usuarios exportados por un Rol de WordPress. <a href=\"%s\" "
|
124 |
+
"target=\"_blank\">%s</a>"
|
125 |
+
|
126 |
+
#: ../export-user-data.php:708
|
127 |
+
msgid "Registered"
|
128 |
+
msgstr "Registrado"
|
129 |
+
|
130 |
+
#: ../export-user-data.php:711
|
131 |
+
msgid "Start Date"
|
132 |
+
msgstr "Fecha de inicio"
|
133 |
+
|
134 |
+
#: ../export-user-data.php:715
|
135 |
+
msgid "End Date"
|
136 |
+
msgstr "Fecha final"
|
137 |
+
|
138 |
+
#: ../export-user-data.php:720
|
139 |
+
msgid "Pick a start and end user registration date to limit the results."
|
140 |
+
msgstr ""
|
141 |
+
"Elige un intervalo de fechas de registro del usuario para reducir los "
|
142 |
+
"resultados."
|
143 |
+
|
144 |
+
#: ../export-user-data.php:727
|
145 |
+
msgid "Limit Range"
|
146 |
+
msgstr "Limitar intervalo"
|
147 |
+
|
148 |
+
#: ../export-user-data.php:730
|
149 |
+
msgid "Total"
|
150 |
+
msgstr "Total"
|
151 |
+
|
152 |
+
#: ../export-user-data.php:742
|
153 |
+
msgid "Format"
|
154 |
+
msgstr "Formato"
|
155 |
+
|
156 |
+
#: ../export-user-data.php:747
|
157 |
+
msgid "Excel"
|
158 |
+
msgstr "Excel"
|
159 |
+
|
160 |
+
#: ../export-user-data.php:748
|
161 |
+
msgid "CSV"
|
162 |
+
msgstr "CSV"
|
163 |
+
|
164 |
+
#: ../export-user-data.php:754
|
165 |
+
msgid "Select the format for the export file."
|
166 |
+
msgstr "Elige el formato para el fichero que se exportará."
|
library/languages/export-user-data-fr_FR.mo
ADDED
Binary file
|
library/languages/export-user-data-fr_FR.po
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Export User Data\n"
|
4 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/export-users-to-csv\n"
|
5 |
+
"POT-Creation-Date: 2014-01-26 00:56+0100\n"
|
6 |
+
"PO-Revision-Date: 2014-03-13 14:08+0100\n"
|
7 |
+
"Last-Translator: aurélie <administratif@urbancube.fr>\n"
|
8 |
+
"Language-Team: urbancube <contact@urbancube.fr>\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"X-Generator: Poedit 1.6.4\n"
|
13 |
+
"X-Poedit-KeywordsList: _;_e;_n;__\n"
|
14 |
+
"X-Poedit-Basepath: .\n"
|
15 |
+
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
16 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
17 |
+
"Language: fr\n"
|
18 |
+
"X-Poedit-SearchPath-0: .\n"
|
19 |
+
"X-Poedit-SearchPath-1: ..\n"
|
20 |
+
|
21 |
+
#: ../export-user-data.php:85 ../export-user-data.php:450
|
22 |
+
msgid "Export User Data"
|
23 |
+
msgstr "Exportez les données utilisateurs."
|
24 |
+
|
25 |
+
#: ../export-user-data.php:445
|
26 |
+
msgid "You do not have sufficient permissions to access this page."
|
27 |
+
msgstr "Vous n'avez pas la permission d'accéder à cette page."
|
28 |
+
|
29 |
+
#: ../export-user-data.php:455
|
30 |
+
msgid "No users found."
|
31 |
+
msgstr "Aucun utilisateur trouvé."
|
32 |
+
|
33 |
+
#: ../export-user-data.php:511
|
34 |
+
msgid "User Meta Fields"
|
35 |
+
msgstr "Champs de balise utilisateurs"
|
36 |
+
|
37 |
+
#: ../export-user-data.php:513
|
38 |
+
msgid "Filter"
|
39 |
+
msgstr "Filtre"
|
40 |
+
|
41 |
+
#: ../export-user-data.php:513
|
42 |
+
msgid "All"
|
43 |
+
msgstr "Tous"
|
44 |
+
|
45 |
+
#: ../export-user-data.php:513
|
46 |
+
msgid "Common"
|
47 |
+
msgstr "Commun"
|
48 |
+
|
49 |
+
#: ../export-user-data.php:564
|
50 |
+
msgid ""
|
51 |
+
"Select the user meta keys to export, use the filters to simplify the list."
|
52 |
+
msgstr ""
|
53 |
+
"Choisissez les balises clés d'utilisateur pour exporter, utiliser les "
|
54 |
+
"filtres pour simplifier la liste."
|
55 |
+
|
56 |
+
#: ../export-user-data.php:593
|
57 |
+
msgid "BP xProfile Fields"
|
58 |
+
msgstr "Champs BP xProfile"
|
59 |
+
|
60 |
+
#: ../export-user-data.php:614
|
61 |
+
msgid "Select the BuddyPress XProfile keys to export"
|
62 |
+
msgstr "Choisissez le bouton BuddyPress XProfile pour exporter"
|
63 |
+
|
64 |
+
#: ../export-user-data.php:626
|
65 |
+
msgid "BP xProfile Fields Update Time"
|
66 |
+
msgstr "Champs de temps passé BP xProfile"
|
67 |
+
|
68 |
+
#: ../export-user-data.php:642
|
69 |
+
msgid "Select the BuddyPress XProfile keys updated dates to export"
|
70 |
+
msgstr ""
|
71 |
+
"Choisissez les touches BuddyPress XProfile des dates mises à jour pour "
|
72 |
+
"exporter"
|
73 |
+
|
74 |
+
#: ../export-user-data.php:653
|
75 |
+
msgid "Role"
|
76 |
+
msgstr "Rôle"
|
77 |
+
|
78 |
+
#: ../export-user-data.php:658
|
79 |
+
msgid "All Roles"
|
80 |
+
msgstr "Tous les rôles"
|
81 |
+
|
82 |
+
#: ../export-user-data.php:668
|
83 |
+
#, php-format
|
84 |
+
msgid ""
|
85 |
+
"Filter the exported users by a WordPress Role. <a href=\"%s\" target=\"_blank"
|
86 |
+
"\">%s</a>"
|
87 |
+
msgstr ""
|
88 |
+
"Filtrez les utilisateurs exportés par un Rôle WordPress. <a href=\"%s\" "
|
89 |
+
"target=\"_blank\">%s</a>"
|
90 |
+
|
91 |
+
#: ../export-user-data.php:682
|
92 |
+
msgid "Programs"
|
93 |
+
msgstr "Programmes"
|
94 |
+
|
95 |
+
#: ../export-user-data.php:687
|
96 |
+
msgid "All Programs"
|
97 |
+
msgstr "Tous les programmes"
|
98 |
+
|
99 |
+
#: ../export-user-data.php:708
|
100 |
+
msgid "Registered"
|
101 |
+
msgstr "Enregistré"
|
102 |
+
|
103 |
+
#: ../export-user-data.php:711
|
104 |
+
msgid "Start Date"
|
105 |
+
msgstr "Date de début"
|
106 |
+
|
107 |
+
#: ../export-user-data.php:715
|
108 |
+
msgid "End Date"
|
109 |
+
msgstr "Date de fin"
|
110 |
+
|
111 |
+
#: ../export-user-data.php:720
|
112 |
+
msgid "Pick a start and end user registration date to limit the results."
|
113 |
+
msgstr ""
|
114 |
+
"Choisissez une date de début et de fin d'enregistrement utilisateur pour "
|
115 |
+
"limiter les résultats."
|
116 |
+
|
117 |
+
#: ../export-user-data.php:727
|
118 |
+
msgid "Limit Range"
|
119 |
+
msgstr "Limite supérieure"
|
120 |
+
|
121 |
+
#: ../export-user-data.php:729
|
122 |
+
msgid "From"
|
123 |
+
msgstr "De"
|
124 |
+
|
125 |
+
#: ../export-user-data.php:730
|
126 |
+
msgid "To"
|
127 |
+
msgstr "A"
|
128 |
+
|
129 |
+
#: ../export-user-data.php:733
|
130 |
+
#, php-format
|
131 |
+
msgid ""
|
132 |
+
"Enter an offset start number and a total number to export. <a href=\"%s\" "
|
133 |
+
"target=\"_blank\">%s</a>"
|
134 |
+
msgstr "Entrez un nombre de début décalé et un nombre total pour exporter"
|
135 |
+
|
136 |
+
#: ../export-user-data.php:742
|
137 |
+
msgid "Format"
|
138 |
+
msgstr "Format"
|
139 |
+
|
140 |
+
#: ../export-user-data.php:747
|
141 |
+
msgid "Excel"
|
142 |
+
msgstr "Excel"
|
143 |
+
|
144 |
+
#: ../export-user-data.php:748
|
145 |
+
msgid "CSV"
|
146 |
+
msgstr "CSV"
|
147 |
+
|
148 |
+
#: ../export-user-data.php:754
|
149 |
+
msgid "Select the format for the export file."
|
150 |
+
msgstr "Choisissez le format d'exportation du fichier."
|
151 |
+
|
152 |
+
#: ../export-user-data.php:762
|
153 |
+
msgid "Advanced Options"
|
154 |
+
msgstr "Options avancées"
|
155 |
+
|
156 |
+
#: ../export-user-data.php:766 ../export-user-data.php:840
|
157 |
+
msgid "Show"
|
158 |
+
msgstr "Montrer"
|
159 |
+
|
160 |
+
#: ../export-user-data.php:774
|
161 |
+
msgid "Export"
|
162 |
+
msgstr "Export"
|
163 |
+
|
164 |
+
#: ../export-user-data.php:838
|
165 |
+
msgid "Hide"
|
166 |
+
msgstr "En cache"
|
readme.md
CHANGED
@@ -1,198 +1,23 @@
|
|
1 |
-
# Export User Data #
|
2 |
-
|
3 |
-
**
|
4 |
-
**
|
5 |
-
**
|
6 |
-
**
|
7 |
-
**
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
* Exports users
|
21 |
-
* Exports users
|
22 |
-
* Exports users by
|
23 |
-
*
|
24 |
-
|
25 |
-
For feature request and bug reports, [please use the Q Support Website](https://qstudio.us/support/categories/export-user-data).
|
26 |
-
|
27 |
-
Please do not use the Wordpress.org forum to report bugs, as we no longer monitor or respond to questions there.
|
28 |
-
|
29 |
-
## Installation ##
|
30 |
-
|
31 |
-
For an automatic installation through WordPress:
|
32 |
-
|
33 |
-
1. Go to the 'Add New' plugins screen in your WordPress admin area
|
34 |
-
2. Search for 'Export User Data'
|
35 |
-
3. Click 'Install Now' and activate the plugin
|
36 |
-
4. Go the 'Export User Data' menu, under 'Users'
|
37 |
-
|
38 |
-
For a manual installation via FTP:
|
39 |
-
|
40 |
-
1. Upload the `export-user-data` directory to the `/wp-content/plugins/` directory
|
41 |
-
2. Activate the plugin through the 'Plugins' screen in your WordPress admin area
|
42 |
-
3. Go the 'Export User Data' menu, under 'Users'
|
43 |
-
|
44 |
-
To upload the plugin through WordPress, instead of FTP:
|
45 |
-
|
46 |
-
1. Upload the downloaded zip file on the 'Add New' plugins screen (see the 'Upload' tab) in your WordPress admin area and activate.
|
47 |
-
2. Go the 'Export User Data' menu, under 'Users'
|
48 |
-
|
49 |
-
## Frequently Asked Questions ##
|
50 |
-
|
51 |
-
### How to use? ###
|
52 |
-
|
53 |
-
Click on the 'Export User Data' link in the 'Users' menu, choose the role and the date range or don't select anything if you want to export all users, then click 'Export'. That's all!
|
54 |
-
|
55 |
-
## Screenshots ##
|
56 |
-
|
57 |
-
### 1. User export screen ###
|
58 |
-
![ScreenShot](http://s.w.org/plugins/export-user-data/screenshot-1.png?r=859689)
|
59 |
-
|
60 |
-
## Changelog ##
|
61 |
-
|
62 |
-
*** 1.3.1 ***
|
63 |
-
* Moved all internal action hooks to admin_init to allow for internal function loading
|
64 |
-
|
65 |
-
*** 1.3.0 ***
|
66 |
-
* Added extra data sanitization before outputting to file - thanks to Hely Shah <helyhshah@gmail.com> for te heads-up
|
67 |
-
|
68 |
-
*** 1.2.8 ***
|
69 |
-
* New: Added load_buddypress() methods to test for buddypress and load up if missing
|
70 |
-
* New: move action hooks and priority to load later
|
71 |
-
* New: Plugin no longer uses singleton model to instatiate - instead called from action hook to public function
|
72 |
-
* New: added log() to debug.log file to help debugging issues
|
73 |
-
* Update: jQuery datepickers pull start_of_week value from WordPress
|
74 |
-
* Tested on 4.4.2
|
75 |
-
|
76 |
-
*** 1.2.7 ***
|
77 |
-
* Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
|
78 |
-
|
79 |
-
*** 1.2.6 ***
|
80 |
-
* Update: WP 4.4.1
|
81 |
-
|
82 |
-
### 1.2.3 ###
|
83 |
-
* Fix: to remove minor security loop hole
|
84 |
-
* New: Added option to remove standard wp_users data from export
|
85 |
-
* Fix: removed roles and groups columns from export when options hidden
|
86 |
-
|
87 |
-
### 1.2.2 ###
|
88 |
-
* Minor FIxes
|
89 |
-
|
90 |
-
### 1.2.1 ###
|
91 |
-
* Checked on WP 4.3.1
|
92 |
-
* Moved text-domain to string in preperation for addition to translate.wordpress.org
|
93 |
-
* Added Log() method to allow for debugging to WP Error Log
|
94 |
-
* Added Greek translation - Thanks @Leonidas Mi
|
95 |
-
* Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
|
96 |
-
|
97 |
-
### 1.2.0 ###
|
98 |
-
* Data stored in recursive and serialized arrays is now exported in a flat string format with safe delimiters ( ||, ||| - etc. )
|
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.0.4 ###
|
107 |
-
* Added unserialize function with @ fallback
|
108 |
-
* Removed anonymous function to allow support for PHP < 5.2
|
109 |
-
|
110 |
-
### 1.0.3 ###
|
111 |
-
* Tested as working on WordPress 4.1.0.
|
112 |
-
|
113 |
-
### 1.0.2 ###
|
114 |
-
* Removed get_user_meta method, as not effective.
|
115 |
-
* Added registration date from and to pickers - to replace monthly <select> lists.
|
116 |
-
|
117 |
-
### 1.0.1 ###
|
118 |
-
* Added recursive_implode() method to flatten data stored in arrays ( exported with keys and values divided by "|" )
|
119 |
-
|
120 |
-
### 1.0.0 ###
|
121 |
-
* Reduced all get_user_meta queries to a single call to improve performance
|
122 |
-
* Serialized data is now returned in it's pure stored format - not imploded or unserialized to avoid data structure loss
|
123 |
-
|
124 |
-
### 0.9.9 ###
|
125 |
-
* get_uermeta renamed get_user_meta to be more consistent with WP
|
126 |
-
* get_user_meta tidied up and tested on larger exports
|
127 |
-
* added option to export user BP Groups
|
128 |
-
* added option to export all user WP Roles
|
129 |
-
|
130 |
-
### 0.9.8 ###
|
131 |
-
* added get_usermeta() to check if meta keys are unique and return an array if not
|
132 |
-
* removed known_arrays() filter to allow for array data to be returned correctly - too hacky
|
133 |
-
|
134 |
-
### 0.9.7 ###
|
135 |
-
* Added known_arrays() filter to allow for array data to be returned correctly
|
136 |
-
|
137 |
-
### 0.9.6 ###
|
138 |
-
* Save, load and delete stored export settings - thanks to @cwjordan
|
139 |
-
* Overcome memory outages on large exports - thanks to @grexican
|
140 |
-
* Tested on WP 4.0.0 & BP 2.1.0
|
141 |
-
|
142 |
-
### 0.9.5 ###
|
143 |
-
* BP Serialized data fixes - thanks to @nicmare & @grexican
|
144 |
-
* Tested on WP 3.9.2 & BP 2.0.2
|
145 |
-
|
146 |
-
### 0.9.4 ###
|
147 |
-
* BP X Profile Export Fix ( > version 2.0 )
|
148 |
-
|
149 |
-
### 0.9.3 ###
|
150 |
-
* fix for hidden admin bar
|
151 |
-
|
152 |
-
### 0.9.2 ###
|
153 |
-
* removed $key assignment casting to integer
|
154 |
-
|
155 |
-
### 0.9.1 ###
|
156 |
-
* Tested with WP 3.9
|
157 |
-
* Fix for BuddyPress 2.0 bug
|
158 |
-
|
159 |
-
### 0.9.0 ###
|
160 |
-
* Moved plugin class to singleton model
|
161 |
-
* Improved language handling
|
162 |
-
* French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
|
163 |
-
|
164 |
-
### 0.8.3 ###
|
165 |
-
* clarified export limit options
|
166 |
-
|
167 |
-
### 0.8.2 ###
|
168 |
-
* corrected buddypress export option - broken in 0.8.1
|
169 |
-
* changed get_users arguments, in attempt to reduce memory usage
|
170 |
-
|
171 |
-
### 0.8.1 ###
|
172 |
-
* Added experimental range limiter for exports
|
173 |
-
* Extra input data sanitizing
|
174 |
-
|
175 |
-
### 0.8 ###
|
176 |
-
* moved plugin instatiation to the WP hook: init
|
177 |
-
* moved bp calls outside export loop
|
178 |
-
* added extra isset calls on values in export loop to clean up error log not sets
|
179 |
-
|
180 |
-
### 0.7.8 ###
|
181 |
-
* added xml template for Excel exports - thanks to phil@fixitlab.com :)
|
182 |
-
|
183 |
-
### 0.7.2 ###
|
184 |
-
* fixes to allow exports without selecting extra user date from usermeta or x-profile
|
185 |
-
|
186 |
-
### 0.6.3 ###
|
187 |
-
* added multiselect to pick usermeta and xprofile fields
|
188 |
-
|
189 |
-
### 0.5 ###
|
190 |
-
* First public release.
|
191 |
-
|
192 |
-
## Upgrade Notice ##
|
193 |
-
|
194 |
-
### 0.6.3 ###
|
195 |
-
Latest.
|
196 |
-
|
197 |
-
### 0.5 ###
|
198 |
-
First release.
|
1 |
+
# Export User Data #
|
2 |
+
|
3 |
+
**Contributors:** qlstudio
|
4 |
+
**Tags:** user, users, xprofile, usermeta csv, excel, batch, export, save, download
|
5 |
+
**Requires at least:** 5.0.0
|
6 |
+
**Tested up to:** 5.0.0
|
7 |
+
**Stable tag:** 2.0.1
|
8 |
+
**License:** GPLv2
|
9 |
+
|
10 |
+
Export users data and metadata to a csv or Excel file
|
11 |
+
|
12 |
+
## Description ##
|
13 |
+
|
14 |
+
A plugin that exports WordPress user data and metadata.
|
15 |
+
|
16 |
+
Includes an option to export the users by role, registration date range, usermeta option and two export formats.
|
17 |
+
|
18 |
+
### Features ###
|
19 |
+
|
20 |
+
* Exports all users fields
|
21 |
+
* Exports users meta
|
22 |
+
* Exports users by role
|
23 |
+
* Exports users by date range
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -1,205 +1,9 @@
|
|
1 |
=== Export User Data ===
|
2 |
Contributors: qlstudio
|
3 |
Tags: user, users, xprofile, usermeta csv, excel, batch, export, save, download
|
4 |
-
Requires at least:
|
5 |
-
Tested up to:
|
6 |
-
Stable tag:
|
7 |
License: GPLv2
|
8 |
|
9 |
-
Export users data
|
10 |
-
|
11 |
-
== Description ==
|
12 |
-
|
13 |
-
A plugin that exports all user data, meta data and BuddyPress xProfile data.
|
14 |
-
|
15 |
-
Includes an option to export the users by role, registration date range, usermeta option and two export formats.
|
16 |
-
|
17 |
-
= Features =
|
18 |
-
|
19 |
-
* Exports all users fields
|
20 |
-
* Exports users meta
|
21 |
-
* Exports users by role
|
22 |
-
* Exports users by date range
|
23 |
-
* Export user BuddyPress xProfile data
|
24 |
-
|
25 |
-
For feature request and bug reports, [please use the Q Support Website](https://qstudio.us/support/categories/export-user-data).
|
26 |
-
|
27 |
-
Please do not use the Wordpress.org forum to report bugs, as we no longer monitor or respond to questions there.
|
28 |
-
|
29 |
-
== Installation ==
|
30 |
-
|
31 |
-
For an automatic installation through WordPress:
|
32 |
-
|
33 |
-
1. Go to the 'Add New' plugins screen in your WordPress admin area
|
34 |
-
2. Search for 'Export User Data'
|
35 |
-
3. Click 'Install Now' and activate the plugin
|
36 |
-
4. Go the 'Export User Data' menu, under 'Users'
|
37 |
-
|
38 |
-
For a manual installation via FTP:
|
39 |
-
|
40 |
-
1. Upload the `export-user-data` directory to the `/wp-content/plugins/` directory
|
41 |
-
2. Activate the plugin through the 'Plugins' screen in your WordPress admin area
|
42 |
-
3. Go the 'Export User Data' menu, under 'Users'
|
43 |
-
|
44 |
-
To upload the plugin through WordPress, instead of FTP:
|
45 |
-
|
46 |
-
1. Upload the downloaded zip file on the 'Add New' plugins screen (see the 'Upload' tab) in your WordPress admin area and activate.
|
47 |
-
2. Go the 'Export User Data' menu, under 'Users'
|
48 |
-
|
49 |
-
== Frequently Asked Questions ==
|
50 |
-
|
51 |
-
= How to use? =
|
52 |
-
|
53 |
-
Click on the 'Export User Data' link in the 'Users' menu, choose the role and the date range or don't select anything if you want to export all users, then click 'Export'. That's all!
|
54 |
-
|
55 |
-
== Screenshots ==
|
56 |
-
|
57 |
-
1. User export screen
|
58 |
-
|
59 |
-
== Changelog ==
|
60 |
-
|
61 |
-
= 1.3.1 =
|
62 |
-
* Moved all internal action hooks to admin_init to allow for internal function loading
|
63 |
-
|
64 |
-
= 1.3.0 =
|
65 |
-
* Added extra data sanitization before outputting to file - thanks to Hely Shah <helyhshah@gmail.com> for the heads-up
|
66 |
-
|
67 |
-
= 1.2.8 =
|
68 |
-
* New: Added load_buddypress() methods to test for buddypress and load up if missing
|
69 |
-
* New: move action hooks and priority to load later
|
70 |
-
* New: Plugin no longer uses singleton model to instatiate - instead called from action hook to public function
|
71 |
-
* New: added log() to debug.log file to help debugging issues
|
72 |
-
* Update: jQuery datepickers pull start_of_week value from WordPress
|
73 |
-
* Tested on 4.4.2
|
74 |
-
|
75 |
-
= 1.2.7 =
|
76 |
-
* Added: Spanish translation - thanks Elías Gómez Sainz ( elias@estudions.es )
|
77 |
-
|
78 |
-
= 1.2.6 =
|
79 |
-
* Update: WP 4.4.1
|
80 |
-
|
81 |
-
= 1.2.4 =
|
82 |
-
* Fix: Removed comments to screen
|
83 |
-
|
84 |
-
= 1.2.3 =
|
85 |
-
* Fix: to remove minor security loop hole
|
86 |
-
* New: Added option to remove standard wp_users data from export
|
87 |
-
* Fix: removed roles and groups columns from export when options hidden
|
88 |
-
|
89 |
-
= 1.2.2 =
|
90 |
-
* Minor Fixes
|
91 |
-
|
92 |
-
= 1.2.1 =
|
93 |
-
* Checked on WP 4.3.1
|
94 |
-
* Moved text-domain to string in preperation for addition to translate.wordpress.org
|
95 |
-
* Added Log() method to allow for debugging to WP Error Log
|
96 |
-
* Added Greek translation - Thanks @Leonidas Mi
|
97 |
-
* Added option to limit export by last_updated date of specific xprofile field - Thanks to @cwjordan
|
98 |
-
|
99 |
-
= 1.2.0 =
|
100 |
-
* Data stored in recursive and serialized arrays is now exported in a flat string format with safer delimiters ( ||, ||| - etc. )
|
101 |
-
* Removed anonymous function calls giving errors on older versions of PHP
|
102 |
-
|
103 |
-
= 1.1.1 =
|
104 |
-
* Removed accidently included .git files
|
105 |
-
|
106 |
-
= 1.1.0 =
|
107 |
-
* Version change to sync SVN on wordpress.org
|
108 |
-
|
109 |
-
= 1.1.1 =
|
110 |
-
* Removed accidently included .git files
|
111 |
-
|
112 |
-
= 1.1.0 =
|
113 |
-
= 1.0.4 =
|
114 |
-
* Added unserialize function with @ fallback
|
115 |
-
* Removed anonymous function to allow support for PHP < 5.2
|
116 |
-
|
117 |
-
= 1.0.3 =
|
118 |
-
* Tested as working on WordPress 4.1.0.
|
119 |
-
|
120 |
-
= 1.0.2 =
|
121 |
-
* Removed get_user_meta method, as not effective.
|
122 |
-
* Added registration date from and to pickers - to replace monthly <select> lists.
|
123 |
-
|
124 |
-
= 1.0.1 =
|
125 |
-
* Added recursive_implode() method to flatten data stored in arrays ( exported with keys and values divided by "|" )
|
126 |
-
|
127 |
-
= 1.0.0 =
|
128 |
-
* Reduced all get_user_meta queries to a single call to improve performance
|
129 |
-
* Serialized data is now returned in it's pure stored format - not imploded or unserialized to avoid data structure loss
|
130 |
-
|
131 |
-
= 0.9.9 =
|
132 |
-
* get_uermeta renamed get_user_meta to be more consistent with WP
|
133 |
-
* get_user_meta tidied up and tested on larger exports
|
134 |
-
* added option to export user BP Groups
|
135 |
-
* added option to export all user WP Roles
|
136 |
-
|
137 |
-
= 0.9.8 =
|
138 |
-
* added get_usermeta() to check if meta keys are unique and return an array if not
|
139 |
-
* removed known_arrays() filter to allow for array data to be returned correctly - too hacky
|
140 |
-
|
141 |
-
= 0.9.7 =
|
142 |
-
* Added known_arrays() filter to allow for array data to be returned correctly
|
143 |
-
|
144 |
-
= 0.9.6 =
|
145 |
-
* Save, load and delete stored export settings - thanks to @cwjordan
|
146 |
-
* Overcome memory outages on large exports - thanks to @grexican
|
147 |
-
* Tested on WP 4.0.0 & BP 2.1.0
|
148 |
-
|
149 |
-
= 0.9.5 =
|
150 |
-
* BP Serialized data fixes - thanks to @nicmare & @grexican
|
151 |
-
* Tested on WP 3.9.2 & BP 2.0.2
|
152 |
-
|
153 |
-
= 0.9.4 =
|
154 |
-
* BP X Profile Export Fix ( > version 2.0 )
|
155 |
-
|
156 |
-
= 0.9.3 =
|
157 |
-
* fix for hidden admin bar
|
158 |
-
|
159 |
-
= 0.9.2 =
|
160 |
-
* removed $key assignment casting to integer
|
161 |
-
|
162 |
-
= 0.9.1 =
|
163 |
-
* Tested with WP 3.9
|
164 |
-
* Fix for BuddyPress 2.0 bug
|
165 |
-
|
166 |
-
= 0.9.0 =
|
167 |
-
* Moved plugin class to singleton model
|
168 |
-
* Improved language handling
|
169 |
-
* French translation - thanks @bastho - http://wordpress.org/support/profile/bastho
|
170 |
-
|
171 |
-
= 0.8.3 =
|
172 |
-
* clarified export limit options
|
173 |
-
|
174 |
-
= 0.8.2 =
|
175 |
-
* corrected buddypress export option - broken in 0.8.1
|
176 |
-
* changed get_users arguments, in attempt to reduce memory usage
|
177 |
-
|
178 |
-
= 0.8.1 =
|
179 |
-
* Added experimental range limiter for exports
|
180 |
-
* Extra input data sanitizing
|
181 |
-
|
182 |
-
= 0.8 =
|
183 |
-
* moved plugin instatiation to the WP hook: init
|
184 |
-
* moved bp calls outside export loop
|
185 |
-
* added extra isset calls on values in export loop to clean up error log not sets
|
186 |
-
|
187 |
-
= 0.7.8 =
|
188 |
-
* added xml template for Excel exports - thanks to phil@fixitlab.com :)
|
189 |
-
|
190 |
-
= 0.7.2 =
|
191 |
-
* fixes to allow exports without selecting extra user date from usermeta or x-profile
|
192 |
-
|
193 |
-
= 0.6.3 =
|
194 |
-
* added multiselect to pick usermeta and xprofile fields
|
195 |
-
|
196 |
-
= 0.5 =
|
197 |
-
* First public release.
|
198 |
-
|
199 |
-
== Upgrade Notice ==
|
200 |
-
|
201 |
-
= 0.6.3 =
|
202 |
-
Latest.
|
203 |
-
|
204 |
-
= 0.5 =
|
205 |
-
First release.
|
1 |
=== Export User Data ===
|
2 |
Contributors: qlstudio
|
3 |
Tags: user, users, xprofile, usermeta csv, excel, batch, export, save, download
|
4 |
+
Requires at least: 4.8.0
|
5 |
+
Tested up to: 5.0.0
|
6 |
+
Stable tag: 2.0.1
|
7 |
License: GPLv2
|
8 |
|
9 |
+
Export users data and metadata to a csv or Excel fil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|