PluginProbe
MyRewards / trunk
MyRewards vtrunk
5.7.8 5.7.7 5.7.6 trunk 1.2.2 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.1 2.2.0 2.3.0 2.4.0 2.4.1 2.5.0 2.6.4 2.6.6 3.0.0.0 3.1.0 3.1.2 3.1.2.1 3.10.4 3.10.9 All 165 releases
woorewards / include / ui / editlists / userspoints.php

userspoints.php in MyRewards trunk, at include/ui/editlists/userspoints.php

214 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace LWS\WOOREWARDS\Ui\Editlists;
3
4 // don't call the file directly
5 if( !defined( 'ABSPATH' ) ) exit();
6
7 /** Display users and their point at backend. */
8 class UsersPoints extends \LWS\Adminpanel\EditList\Source
9 {
10 const L_PREFIX = 'lws_wre_pool_';
11 const S_PREFIX = 'lws_wre_points_';
12
13 protected $sortSource = false;
14 protected $stackIds = false;
15
16 public function getEditCapability(): string
17 {
18 return 'manage_rewards';
19 }
20
21 function labels()
22 {
23 $default = \LWS_WooRewards::getInstalledPool();
24 if (!$default) {
25 $prefabs = \LWS_WooRewards::getPrefabPools(false);
26 if ($prefabs)
27 $default = $prefabs->first();
28 }
29 $column = self::L_PREFIX . ($default ? $default->getId() : 'default');
30 $labels = array(
31 'user' => array(__("Users", 'woorewards-lite'), '1fr'),
32 $column => array(\LWS_WooRewards::getPointSymbol(2, $default), 'max-content'), // usermeta 'lws_wre_points_default'
33 'rewards' => array(__("Rewards", 'woorewards-lite'), 'auto'), // filled by filter
34 );
35 return \apply_filters('lws_woorewards_ui_userspoints_labels', $labels);
36 }
37
38 function read($limit)
39 {
40 global $wpdb;
41 $request = \LWS\Adminpanel\Tools\Request::from($wpdb->users, 'u');
42 $request->select('u.ID as user_id, u.*');
43 $request->group('u.ID');
44 $request->rowLimit($limit);
45 $this->addSorting($request);
46
47 $request = \apply_filters('lws_woorewards_admin_userspoints_request', $this->search($request), true);
48 $users = $request->getResults(ARRAY_A);
49 if (!$users)
50 return array();
51 else
52 return \array_map(array($this, 'shapeRow'), $users);
53 }
54
55 function shapeRow($user)
56 {
57 global $wpdb;
58 // get all points for that user
59 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
60 $points = $wpdb->get_results($wpdb->prepare(
61 "SELECT meta_key, meta_value FROM {$wpdb->usermeta} WHERE user_id = %d AND meta_key LIKE %s",
62 (int)$user['user_id'],
63 self::S_PREFIX . '%'
64 ), OBJECT_K);
65 // format them
66 foreach ($this->getStackIds() as $info) {
67 $column = (self::L_PREFIX . $info->post_id);
68 $key = (self::S_PREFIX . $info->stack_id);
69 $amount = (isset($points[$key]) ? $points[$key]->meta_value : 0);
70 $user[$key] = \LWS_WooRewards::formatPoints($amount, $info->post_id);
71 $user[$column] = sprintf(
72 "<a class='lws_wre_point_history maxwidth right lws-icon-time-machine' data-stack='%s' data-user='%d'>%s</a>",
73 \esc_attr($info->stack_id),
74 (int)$user['user_id'],
75 \apply_filters('lws_wre_editlist_point_amount_display', $user[$key], $user, $info->post_id, $info)
76 );
77 }
78 // user name
79 $edit = esc_attr(\get_edit_user_link($user['user_id']));
80 $mailto = esc_attr('mailto:' . $user['user_email']);
81 $display = \apply_filters('lws_woorewards_customer_display_name', $user['display_name'], $user);
82 $user['user'] = implode(' - ', array(
83 "<a href='{$edit}' target='_blank'>{$user['user_login']}</a>",
84 "<a href='{$mailto}'>{$user['user_email']}</a>",
85 "<span class='lws_wre_history_dispname'>{$display}</span>"
86 ));
87 // rewards
88 $user['rewards'] = "<div class='lws-editlist-btns-line'>";
89 $user['rewards'] .= implode('', \apply_filters('lws_woorewards_ui_userspoints_rewards_cell', array(), $user));
90 $user['rewards'] .= "</div>";
91 // return modified value
92 return $user;
93 }
94
95 /** @return array as [string:pool_name] => object{post_name, stack_id} */
96 protected function getStackIds()
97 {
98 if (false === $this->stackIds)
99 {
100 global $wpdb;
101 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
102 $this->stackIds = $wpdb->get_results("SELECT post_id, post_name, meta_value as stack_id FROM {$wpdb->postmeta} INNER JOIN {$wpdb->posts} ON ID=post_id WHERE meta_key='wre_pool_point_stack'", OBJECT_K);
103 }
104 return $this->stackIds;
105 }
106
107 function total()
108 {
109 global $wpdb;
110 $request = \LWS\Adminpanel\Tools\Request::from($wpdb->users, 'u');
111 $request->select('COUNT(u.ID)');
112 $request = \apply_filters('lws_woorewards_admin_userspoints_request', $this->search($request), false);
113 $c = $request->getVar();
114 return (\is_null($c) ? -1 : $c);
115 }
116
117 /** @return object the given $sql array with WHERE clause if required. */
118 protected function search($request)
119 {
120 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- admin editlist search
121 $needle = isset($_REQUEST['usersearch']) ? \sanitize_text_field(\wp_unslash($_REQUEST['usersearch'])) : '';
122 if ($needle) {
123 global $wpdb;
124 $mask = ("'%" . \esc_sql($needle) . "%'");
125 $where = array(
126 'condition' => 'OR',
127 "u.user_login LIKE {$mask}",
128 "u.user_email LIKE {$mask}",
129 "u.display_name LIKE {$mask}",
130 "u.user_nicename LIKE {$mask}",
131 );
132 if (($id = \intval($needle)) > 0)
133 $where[] = "u.ID = {$id}";
134 if (\get_option('lws_woorewards_admin_userspoints_deep_search', 'on'))
135 $where[] = "u.ID IN (SELECT m.user_id FROM {$wpdb->usermeta} as m WHERE m.meta_value LIKE {$mask} AND (m.meta_key LIKE '%name' OR m.meta_key LIKE 'billing_%'))";
136 $request->where($where);
137 }
138 return $request;
139 }
140
141 protected function addSorting(&$request)
142 {
143 $asc = !$this->isSortDescsending('userspoints');
144 $value = $this->getSortValue('userspoints');
145 if ($value) {
146 $value = explode('-', $value, 2);
147 if (count($value) > 1) {
148 global $wpdb;
149 // need usermeta points
150 $request->leftJoin($wpdb->usermeta, 'csort', $wpdb->prepare(
151 'csort.user_id=u.ID AND csort.meta_key=%s',
152 'lws_wre_points_' . $value[1]
153 ));
154 // numerical order on casted or inexistant value
155 return $request->order(
156 'CASE WHEN csort.meta_value IS NOT NULL THEN CAST(csort.meta_value AS SIGNED) ELSE 0 END',
157 $asc
158 );
159 } elseif ('email' == $value[0]) {
160 return $request->order('u.user_email', $asc);
161 } elseif ('name' == $value[0]) {
162 return $request->order('u.display_name', $asc);
163 }
164 }
165 return $request->order('u.user_login', $asc);
166 }
167
168 public function getSortColumns()
169 {
170 if (false === $this->sortSource) {
171 global $wpdb;
172 $sql = "SELECT pool.ID, stack.meta_value as stack_id, pool.post_title"
173 . " FROM {$wpdb->posts} as `pool`"
174 . " LEFT JOIN {$wpdb->postmeta} AS stack ON stack.post_id=pool.ID AND stack.meta_key='wre_pool_point_stack'"
175 . " WHERE post_type=%s AND post_status NOT IN ('trash')"
176 . " ORDER BY post_title ASC";
177 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
178 $stacks = $wpdb->get_results($wpdb->prepare($sql, \LWS\WOOREWARDS\Core\Pool::POST_TYPE));
179
180 $this->sortSource = array(
181 array('value' => '', 'label' => __("User Login", 'woorewards-lite')), // user_login
182 array('value' => 'email', 'label' => __("Email", 'woorewards-lite')), // user_email
183 array('value' => 'name', 'label' => __("Display Name", 'woorewards-lite')), // display_name
184 );
185 /* translators: %s: loyalty system name */
186 $label = __("Points : %s", 'woorewards-lite');
187 foreach($stacks as $stack) {
188 $this->sortSource[] = array(
189 'value' => ($stack->ID . '-' . $stack->stack_id),
190 'label' => sprintf($label, $stack->post_title),
191 );
192 }
193 }
194 return $this->sortSource;
195 }
196
197 /** no edition, use bulk action */
198 function input()
199 {
200 return '';
201 }
202
203 /** no edition, use bulk action */
204 function write($row)
205 {
206 return false;
207 }
208
209 /** Cannot erase a user here. */
210 function erase($row)
211 {
212 return false;
213 }
214 }