7e549b89 by Chris Boden

Merging UserSearch for live (232:234, 235:236)

1 parent 9e540a3e
...@@ -21,15 +21,15 @@ use Tz\WordPress\CBV\CEHours; ...@@ -21,15 +21,15 @@ use Tz\WordPress\CBV\CEHours;
21 use Tz\WordPress\CBV\Invoice; 21 use Tz\WordPress\CBV\Invoice;
22 use Tz\WordPress\CBV\Courses; 22 use Tz\WordPress\CBV\Courses;
23 use Tz\WordPress\CBV\CBVOptions; 23 use Tz\WordPress\CBV\CBVOptions;
24 use Exception, StdClass; 24 use Exception, StdClass, ArrayAccess, Iterator, Countable;
25 25
26 const OPTION_NAME = "user_options"; 26 const OPTION_NAME = "user_options";
27 const CAPABILITY = "manage_cbv_users"; 27 const CAPABILITY = "manage_cbv_users";
28 28
29 29
30 CBV\load('Invoice'); 30 CBV\load('Invoice');
31 CBV\load('User'); 31 CBV\load('User');
32 Tools\import('HTML'); 32 Tools\import('HTML');
33 33
34 34
35 call_user_func(function() { 35 call_user_func(function() {
...@@ -92,80 +92,23 @@ function create_instant_invoice($id = 0) { ...@@ -92,80 +92,23 @@ function create_instant_invoice($id = 0) {
92 } 92 }
93 93
94 function get_users($role = null, $pagenum=1, $records_per_page=0, $return_count_only = false, $search = null) { 94 function get_users($role = null, $pagenum=1, $records_per_page=0, $return_count_only = false, $search = null) {
95 global $wpdb; 95 $fs = Array();
96 96 if (!is_null($role)) {
97 $users = array(); 97 $len = strlen($role);
98 98 $fs = Array('wp_capabilities' => "a:1:{s:{$len}:\\\\\\\\\"{$role}\\\\\\\\\"");
99 if ($search) { 99 }
100 $search = strip_tags($search); 100
101 $search_text = "AND (uml.meta_value LIKE '%$search%' OR umf.meta_value LIKE '%$search%' OR u.user_email LIKE '%$search%' OR u.user_login LIKE '%$search%')"; 101 $users = new Tools\UserSearch(
102 } else { 102 Array('member_id', 'first_name', 'last_name', 'home_email', 'work_email', 'email_address_preference', 'status', 'wp_capabilities')
103 $search_text = ""; 103 , $records_per_page
104 } 104 , $pagenum
105 105 , 'last_name'
106 106 , 'ASC'
107 107 , $fs
108 $blog_prefix = $wpdb->get_blog_prefix(); 108 , $search
109 if ($role) { 109 );
110 $extra_table = "";//", {$wpdb->usermeta} as umc"; 110
111 //$filter = "AND (umc.user_id=u.ID AND umc.meta_key='wp_capabilites' AND umc.meta_value LIKE '%$role%')"; 111 $users->setUserClass('Tz\WordPress\CBV\User\Account');
112 $filter = "AND u.ID IN (SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key='wp_capabilities' AND meta_value LIKE '%" . $wpdb->escape($role) . "%')";
113 } else {
114 $extra_table = "";
115 $filter = "";
116 }
117
118 if ($return_count_only) {
119 $query = "
120 SELECT
121 COUNT(*)
122 FROM
123 {$wpdb->users} as u, {$wpdb->usermeta} as uml, {$wpdb->usermeta} as umf, {$wpdb->usermeta} as ums $extra_table
124 WHERE
125 (uml.user_id=u.ID AND uml.meta_key='last_name')
126 AND (umf.user_id=u.ID AND umf.meta_key='first_name')
127 AND (ums.user_id=u.ID AND ums.meta_key='status')
128 $filter
129 $search_text";
130
131 return $count = $wpdb->get_var($query);
132 }
133
134 $query = "
135 SELECT
136 u.ID, u.user_login, user_email, uml.meta_value as last_name, umf.meta_value as first_name
137 FROM
138 {$wpdb->users} as u, {$wpdb->usermeta} as uml, {$wpdb->usermeta} as umf, {$wpdb->usermeta} as ums $extra_table
139 WHERE
140 (uml.user_id=u.ID AND uml.meta_key='last_name')
141 AND (umf.user_id=u.ID AND umf.meta_key='first_name')
142 AND (ums.user_id=u.ID AND ums.meta_key='status')
143 $filter
144 $search_text
145 ORDER BY last_name ASC, first_name ASC
146 ";
147 /*
148 $query = "
149 SELECT u.ID, u.user_login, CONCAT('{', GROUP_CONCAT(CONCAT('"', m.meta_key, '"', ':', '"', m.meta_value, '"')), '}') AS meta_data, (SELECT meta_value FROM wp_usermeta as mt where meta_key = 'last_name' and mt.user_id = u.ID) AS ln
150 FROM wp_users as u left join wp_usermeta as m on u.ID = m.user_id where m.meta_key IN ('first_name', 'last_name')
151 GROUP BY u.ID
152 ORDER BY ln;
153 ");
154 */
155
156
157 if ($records_per_page > 0) {
158 $limit = " LIMIT ".( ($pagenum - 1) * $records_per_page ).", $records_per_page";
159 } else {
160 $limit = "";
161 }
162
163 $wp_user_search = $wpdb->get_results($query . $limit);
164
165 foreach ($wp_user_search as $user ) {
166 $user = new User\Account((int)$user->ID);
167 $users[] = Array('uid' => $user->ID, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'role' => $user->getRole(), 'user_login' => $user->user_login, 'email' => $user->user_email, 'status' => $user->status, 'member_id' => $user->member_id);
168 }
169 return $users; 112 return $users;
170 } 113 }
171 114
......
...@@ -12,27 +12,28 @@ use Tz\WordPress\Tools\Notifications; ...@@ -12,27 +12,28 @@ use Tz\WordPress\Tools\Notifications;
12 12
13 use Exception, StdClass; 13 use Exception, StdClass;
14 use WP_User; 14 use WP_User;
15 ini_set('display_errors', 1);
16 $records_per_page = 20;
17 15
18 $filter_role = isset($_GET['role']) ? $_GET['role'] : null; 16 ini_set('display_errors', 1);
19 $pagenum = isset($_GET['pagenum']) ? $_GET['pagenum'] : 1;
20 $search = isset($_GET['search_criteria']) ? $_GET['search_criteria'] : null;
21 17
22 $rows = get_users($filter_role, 0, 0, true, $search); 18 $records_per_page = 20;
23 19
24 $last = ceil($rows/$records_per_page); 20 $filter_role = isset($_GET['role']) ? $_GET['role'] : null;
25 if ($last < 1) { 21 $pagenum = isset($_GET['pagenum']) ? $_GET['pagenum'] : 1;
26 $last = 1; 22 $search = isset($_GET['search_criteria']) ? $_GET['search_criteria'] : null;
27 }
28 23
29 if ($pagenum < 1) { 24 $site_users = get_users($filter_role, $pagenum, $records_per_page, false, $search);
30 $pagenum = 1; 25 $rows = $site_users->countTotal();
31 } elseif ($pagenum > $last) {
32 $pagenum = $last;
33 }
34 26
35 $site_users = get_users($filter_role, $pagenum, $records_per_page, false, $search); 27 $last = ceil($rows/$records_per_page);
28 if ($last < 1) {
29 $last = 1;
30 }
31
32 if ($pagenum < 1) {
33 $pagenum = 1;
34 } elseif ($pagenum > $last) {
35 $pagenum = $last;
36 }
36 37
37 if ($filter_role) { 38 if ($filter_role) {
38 $url = $_SERVER['PHP_SELF']."?page=cbv_users&role=$filter_role&pagenum="; 39 $url = $_SERVER['PHP_SELF']."?page=cbv_users&role=$filter_role&pagenum=";
...@@ -171,9 +172,8 @@ if ($last > 1) { ...@@ -171,9 +172,8 @@ if ($last > 1) {
171 <table cellspacing="0" class="widefat post fixed"> 172 <table cellspacing="0" class="widefat post fixed">
172 <thead> 173 <thead>
173 <tr> 174 <tr>
174 <th scope="col" class="manage-column">ID</th>
175 <th scope="col" class="manage-column">Name</th> 175 <th scope="col" class="manage-column">Name</th>
176 <th scope="col" width="180" class="manage-column">Username</th> 176 <th scope="col" width="180" class="manage-column">Member ID</th>
177 <th scope="col" width="250" class="manage-column">Email</th> 177 <th scope="col" width="250" class="manage-column">Email</th>
178 <th scope="col" width="200" class="manage-column">Role</th> 178 <th scope="col" width="200" class="manage-column">Role</th>
179 <th scope="col" width="100" class="manage-column">Status</th> 179 <th scope="col" width="100" class="manage-column">Status</th>
...@@ -184,18 +184,20 @@ if ($last > 1) { ...@@ -184,18 +184,20 @@ if ($last > 1) {
184 </thead> 184 </thead>
185 <tbody> 185 <tbody>
186 <?php 186 <?php
187 187 foreach ($site_users as $user):
188 foreach($site_users as $user): 188 $pref = strtolower($user->email_address_preference);
189 if (!in_array($pref, Array('home', 'work'))) {
190 $pref = (empty($user->home_email) ? 'work' : 'home');
191 }
189 ?> 192 ?>
190 <tr> 193 <tr>
191 <td><?php echo $user['member_id']?></td> 194 <td><a href="/wp-admin/admin.php?page=cbv_users&action=edit&uid=<?php echo $user->id; ?>"><?php echo $user->last_name . ', ' . $user->first_name; ?></a></td>
192 <td><a href="/wp-admin/admin.php?page=cbv_users&action=edit&uid=<?php echo $user['uid']?>"><?php echo $user['last_name'].', '.$user['first_name']?></a></td> 195 <td><a href="/wp-admin/admin.php?page=cbv_users&action=edit&uid=<?php echo $user->id; ?>"><?php echo $user->member_id; ?></a></td>
193 <td><a href="/wp-admin/admin.php?page=cbv_users&action=edit&uid=<?php echo $user['uid']?>"><?php echo $user['user_login']?></a></td> 196 <td><?php echo $user->{$pref . '_email'}; ?></td>
194 <td><?php echo $user['email']?></td> 197 <td><?php echo current(array_keys($user->wp_capabilities)); ?></td>
195 <td><?php echo $user['role']?></td> 198 <td><?php echo ucwords($user->status);?></td>
196 <td><?php echo ucwords($user['status']);?></td>
197 199
198 <td><a href="/wp-admin/admin-ajax.php?ajax=yes&action=build_user_remove&uid=<?php echo $user['uid'];?>" class="remove-user" rel="<?php echo $user['uid'];?>">Remove User</a></td> 200 <td><a href="/wp-admin/admin-ajax.php?ajax=yes&action=build_user_remove&uid=<?php echo $user->user_id;?>" class="remove-user" rel="<?php echo $user->user_id;?>">Remove User</a></td>
199 201
200 </tr> 202 </tr>
201 <?php endforeach; ?> 203 <?php endforeach; ?>
...@@ -211,4 +213,4 @@ if ($last > 1) { ...@@ -211,4 +213,4 @@ if ($last > 1) {
211 <div style="clear:both;"></div> 213 <div style="clear:both;"></div>
212 214
213 </div> 215 </div>
214 <script src="<?php echo Tools\url('../UserManager.js', __FILE__);?>" type="text/javascript"></script> 216 <script src="<?php echo Tools\url('../UserManager.js', __FILE__);?>" type="text/javascript"></script>
...\ No newline at end of file ...\ No newline at end of file
......
1 <?php
2 namespace Tz\WordPress\Tools;
3 use WP_User;
4
5 class User {
6 public $ID = 0;
7 public $id = 0;
8
9 protected $_wpuser;
10 public $_metacache = Array(); // should be protected, need to figure out how invisible byte works with serialize and not using base64 encode
11
12 public function __construct($id, $name = '', $blog_id = '') {
13 $this->_wpuser = new WP_User($id, $name, $blog_id);
14 $this->id = $this->ID = $this->_wpuser->id;
15 }
16
17 public function __get($key) {
18 if (isset($this->_wpuser->{$key})) {
19 return $this->_wpuser->{$key};
20 }
21
22 return $this->getMeta($key, true);
23 }
24
25 public function __set($key, $val) {
26 $this->setMeta($key, $val);
27 }
28
29 public function __sleep() {
30 return Array('_metacache', 'id', 'ID');
31 }
32
33 public function __wakeup() {
34 $this->_wpuser = new WP_User(0);
35
36 // For some (stupid) reason, WP_User has these 2 meta_key fields in its global parameters...
37 if (isset($this->_metacache['first_name'])) {
38 $this->_wpuser->first_name = $this->_metacache['first_name'];
39 }
40
41 if (isset($this->_metacache['last_name'])) {
42 $this->_wpuser->last_name = $this->_metacache['last_name'];
43 }
44 }
45
46 public function __call($method, $params) {
47 if (method_exists($this->_wpuser, $method)) {
48 $this->setUser();
49 return call_user_func_array(Array($this->_wpuser, $method), $params);
50 }
51
52 $classname = get_class($this->_wpuser);
53 trigger_error("Call to undefined method {$class}::{$method}() in " . __FILE__ . " on line " . __LINE__, E_USER_ERROR);
54 }
55
56 protected function setUser() {
57 if ($this->id != $this->_wpuser->id) {
58 $this->_wpuser = new WP_User($this->id);
59 }
60 }
61
62 public function getMeta($key, $single = true) {
63 if (isset($this->_metacache[$key])) {
64 return $this->_metacache[$key];
65 }
66
67 return get_user_meta($this->ID, $key, $single);
68 }
69
70 public function setMeta($key, $val) {
71 update_user_meta($this->ID, $key, $val);
72 unset($this->_metacache[$key]);
73 }
74 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Tz\WordPress\Tools;
3 use ArrayAccess, Iterator, Countable;
4
5 /*
6 Get all active CBV users who are subscribers
7
8 $users = new UserSearch(
9 Array('first_name', 'last_name')
10 , -1
11 , 1
12 , 'last_name'
13 , 'ASC'
14 , Array('status' => 'active')
15 , null
16 , Array(16)
17 );
18 $user->setUserClass('Tz\WordPress\CBV\User\Account');
19
20 // Each $user is an Account (extension of) Tools\User (extension of) WP_User object
21 foreach ($users as $i => $user) {
22 echo "{$user->first_name} {$user->last_name} ($user->getRole()}";
23 }
24
25 // Note, although the example is tailored for CBV, this will work with all WordPress installs
26 */
27
28 class UserSearch implements ArrayAccess, Iterator, Countable {
29 protected $result;
30 protected $pos = 0;
31
32 protected $count = 0;
33 protected $num_rows = 0;
34
35 protected $fields = Array();
36
37 protected $userclass = 'User';
38
39 public function __construct(Array $fields, $num_results = -1, $page = 1, $sortby = null, $sortorder = 'ASC', Array $field_match = null, $text_search = null, Array $in_groups = null) {
40 $this->userclass = __NAMESPACE__ . '\User';
41
42 global $wpdb;
43
44 $this->fields = $fields;
45 $search_clause = $limit_clause = $order_clause = $order_sort = $having_clause = $uam_join = $uam_clause = '';
46
47 // Field matches
48 $having = " HAVING `json` LIKE ";
49 if (is_array($field_match) && count($field_match) > 0) {
50 foreach ($field_match as $key => $val) {
51 if (!in_array($key, $this->fields)) {
52 $this->fields[] = $key;
53 }
54
55 $having_clause .= (empty($having_clause) ? $having : "\n AND `json` LIKE ");
56 $having_clause .= " '%\"{$key}\":\"{$val}%' ";
57 }
58 }
59
60 // Open ended search
61 if (!is_null($text_search)) {
62 $search_strings = explode(' ', $text_search);
63
64 foreach ($search_strings as $search) {
65 $having_clause .= (empty($having_clause) ? $having : "\n AND `json` LIKE ");
66 $having_clause .= " '%{$search}%' ";
67 }
68 }
69
70 // Order
71 if (!is_null($sortby)) {
72 $order_clause = " , GROUP_CONCAT(IF(`meta_key` = '{$sortby}', `meta_value`, '') SEPARATOR '') AS `fake_order` ";
73 $order_sort = " ORDER BY `fake_order` " . ($sortorder == 'DESC' ? 'DESC' : 'ASC');
74 }
75
76 // Pagination
77 if ($num_results > 0) {
78 $limit_clause = " LIMIT " . (($page - 1) * $num_results ) . ", {$num_results}";
79 }
80
81 // Groups
82 if (is_array($in_groups) && count($in_groups) > 0 && is_plugin_active('tz-user-access-manager/user-access-manager.php')) {
83 $uam_join = " LEFT JOIN `wp_uam_accessgroup_to_object` AS `uam` ON `wp_usermeta`.`user_id` = `uam`.`object_id` ";
84 $uam_clause = " AND `uam`.`object_type` = 'user' AND `uam`.`group_id` IN (" . implode(',', $in_groups) . ") ";
85 }
86
87 mysql_query("SET SESSION group_concat_max_len = 40960", $wpdb->dbh);
88
89 $query = "
90 SELECT SQL_CALC_FOUND_ROWS
91 `user_id`
92 , CONCAT(
93 '{'
94 , GROUP_CONCAT(
95 '\"'
96 , `meta_key`
97 , '\":\"'
98 , REPLACE(REPLACE(REPLACE(`meta_value`, '" . '"' . "', '" . '\\\"' . "'), '\\r', '\\\\r'), '\\n', '\\\\n')
99 , '\"'
100 )
101 , '}'
102 ) AS `json`
103 {$order_clause}
104 FROM `wp_usermeta`
105 {$uam_join}
106 WHERE
107 `meta_key` IN ('" . implode("','", $this->fields) . "')
108 {$uam_clause}
109 GROUP BY `user_id`
110 {$having_clause}
111 {$order_sort}
112 {$limit_clause}
113 ";
114 /*
115 ?>
116 <textarea style="width: 95%; height: 35em; font-size: 11px;" autofocus="autofocus">
117 <?php echo trim($query); ?>;
118 </textarea>
119 <?php
120 /**/
121 $this->result = mysql_query($query, $wpdb->dbh);
122 $this->num_rows = mysql_num_rows($this->result);
123
124 $count_result = mysql_query("SELECT FOUND_ROWS()", $wpdb->dbh);
125 list($this->count) = mysql_fetch_row($count_result);
126 }
127
128 public function setUserClass($classname) {
129 $this->userclass = $classname;
130 }
131
132 public function countTotal() {
133 return $this->count;
134 }
135
136 public function count() {
137 return $this->num_rows;
138 }
139
140 public function current() {
141 return $this->offsetGet($this->pos);
142 }
143
144 public function key() {
145 return $this->pos;
146 }
147
148 public function next() {
149 $this->pos++;
150 }
151
152 public function rewind() {
153 $this->current = 0;
154
155 if ($this->num_rows > 0) {
156 mysql_data_seek($this->result, 0);
157 }
158 }
159
160 public function valid() {
161 return $this->offsetExists($this->pos);
162 }
163
164 public function offsetExists($offset) {
165 if ($this->num_rows == 0) {
166 return false;
167 }
168
169 return ($offset < 0 || $offset > ($this->num_rows - 1) ? false : true);
170 }
171
172 public function offsetGet($offset) {
173 if (!$this->offsetExists($offset)) {
174 return false;
175 }
176
177 if ($offset != $this->pos) {
178 mysql_data_seek($this->result, $offset);
179 }
180
181 list($user_id, $user_string) = mysql_fetch_row($this->result);
182 $data = array_merge(array_map(function() { return ''; }, array_flip($this->fields)), json_decode($user_string, true));
183 foreach ($data as $key => &$val) {
184 $val = maybe_unserialize($val);
185 }
186
187 return unserialize(sprintf(
188 'O:%5$d:"%4$s":3:{s:10:"_metacache";%3$ss:2:"id";s:%2$d:"%1$d";s:2:"ID";s:%2$d:"%1$d";}'
189 , $user_id
190 , strlen($user_id)
191 , serialize($data)
192 , $this->userclass
193 , strlen($this->userclass)
194 ));
195 }
196
197 public function offsetSet($offset, $value) {
198 throw new Exception("You're...you're crazy man. I like you, but you're crazy.");
199 }
200
201 public function offsetUnset($offset) {
202 throw new Exception("You're...you're crazy man. I like you, but you're crazy.");
203 }
204 }
205 /*
206
207 class UserInjector extends Pimple {
208 public function __construct(Array $config = null) {
209 $this += $config;
210 }
211 }
212 */
...\ No newline at end of file ...\ No newline at end of file