PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.3
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.3
4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / WordPress / Users / UsersService.php
surecart / app / src / WordPress / Users Last commit date
CustomerLinkService.php 6 days ago UsersService.php 6 days ago UsersServiceProvider.php 4 years ago
UsersService.php
265 lines
1 <?php
2
3 namespace SureCart\WordPress\Users;
4
5 use SureCart\Models\User;
6
7 /**
8 * WordPress Users service.
9 */
10 class UsersService {
11 /**
12 * Register rest related queries.
13 *
14 * @return void
15 */
16 public function bootstrap() {
17 add_filter( 'rest_user_query', array( $this, 'userMetaQuery' ), 10, 2 );
18 add_filter( 'rest_user_query', array( $this, 'isCustomerQuery' ), 10, 2 );
19 add_filter( 'rest_user_collection_params', array( $this, 'collectionParams' ) );
20 add_filter( 'show_admin_bar', array( $this, 'disableAdminBar' ), 10, 1 );
21 add_action( 'profile_update', array( $this, 'syncUserProfile' ), 10, 3 );
22 add_action( 'surecart/customer_updated', array( $this, 'syncCustomerProfile' ) );
23 $this->registerMeta();
24 }
25
26 /**
27 * Fires immediately after an existing customer is updated.
28 *
29 * @param object $customer Customer Data.
30 */
31 public function syncCustomerProfile( $customer ) {
32 $wp_user = \SureCart\Models\User::findByCustomerId( $customer->id );
33
34 if ( ! empty( $wp_user->ID ) ) {
35 $this->applyCustomerToWPUser( $wp_user, $customer );
36 }
37
38 return $wp_user;
39 }
40
41 /**
42 * Apply a customer's profile fields to its linked WP user.
43 *
44 * Shared by the webhook-driven syncCustomerProfile() and the REST-driven
45 * customer edit flow so the "never sync email" rule lives in one place.
46 * Intentionally NOT syncing user_email — CVE-2026-7655 (account takeover via lost-password).
47 *
48 * @param \WP_User $wp_user The linked WP user.
49 * @param object $customer Customer data.
50 *
51 * @return int|\WP_Error The updated user ID or a WP_Error.
52 */
53 public function applyCustomerToWPUser( $wp_user, $customer ) {
54 // prevent potential infinite loop of catching a webhook/request and updating again.
55 remove_action( 'profile_update', array( $this, 'syncUserProfile' ), 10 );
56
57 $result = wp_update_user(
58 array(
59 'ID' => $wp_user->ID,
60 'first_name' => ! empty( $customer->first_name ) ? $customer->first_name : $wp_user->first_name,
61 'last_name' => ! empty( $customer->last_name ) ? $customer->last_name : $wp_user->last_name,
62 'phone' => ! empty( $customer->phone ) ? $customer->phone : $wp_user->phone,
63 )
64 );
65
66 // re-add profile_update in case it is done in the same request somewhere.
67 add_action( 'profile_update', array( $this, 'syncUserProfile' ), 10 );
68
69 return $result;
70 }
71
72 /**
73 * Fires immediately after an existing user is updated.
74 *
75 * @param int $user_id User ID.
76 * @param WP_User $old_user_data Object containing user's data prior to update.
77 * @param array $userdata The raw array of data passed to wp_insert_user().
78 */
79 public function syncUserProfile( $user_id, $old_user_data, $userdata ) {
80 $customer_ids = \SureCart\Models\User::find( $user_id )->customerIds();
81 if ( is_wp_error( $customer_ids ) || empty( $customer_ids ) ) {
82 return;
83 }
84
85 foreach ( $customer_ids as $id ) {
86 \SureCart\Models\Customer::update(
87 array_filter(
88 array(
89 'id' => $id,
90 'first_name' => $userdata['first_name'],
91 'last_name' => $userdata['last_name'],
92 'email' => $userdata['user_email'],
93 'phone' => $userdata['phone'] ?? null,
94 ),
95 function ( $x ) {
96 return null !== $x;
97 }
98 )
99 );
100 }
101 }
102
103 /**
104 * Prevent any user who cannot 'edit_posts' (subscribers, customers etc) from seeing the admin bar.
105 *
106 * @param bool $show_admin_bar If should display admin bar.
107 * @return bool
108 */
109 public function disableAdminBar( $show_admin_bar ) {
110 if ( apply_filters( 'surecart_disable_admin_bar', true ) && ! ( current_user_can( 'edit_posts' ) || current_user_can( 'manage_sc_shop_settings' ) ) ) {
111 return false;
112 }
113
114 return $show_admin_bar;
115 }
116
117 /**
118 * Add our query parameters to the rest api.
119 *
120 * @param array $query_params The query parameters.
121 * @return array
122 */
123 public function collectionParams( $query_params ) {
124 $query_params['is_customer'] = array(
125 'description' => __( 'Limit result set to users with a customer.', 'surecart' ),
126 'type' => 'boolean',
127 );
128 $query_params['sc_customer_ids'] = array(
129 'description' => __( 'Limit result set to users with specific customer ids.', 'surecart' ),
130 'type' => 'array',
131 'items' => array(
132 'type' => 'string',
133 ),
134 );
135 return $query_params;
136 }
137
138 /**
139 * Register customer id meta.
140 *
141 * @return void
142 */
143 public function registerMeta() {
144 register_meta(
145 'user',
146 'sc_customer_ids',
147 array(
148 'type' => 'object',
149 'show_in_rest' => array(
150 'schema' => array(
151 'type' => 'object',
152 'properties' => array(
153 'live' => array(
154 'type' => 'string',
155 ),
156 'test' => array(
157 'type' => 'string',
158 ),
159 ),
160 ),
161 ),
162 'single' => true,
163 'sanitize_callback' => function ( $value ) {
164 return array_filter( array_map( 'sanitize_text_field', (array) $value ) );
165 },
166 'auth_callback' => function () {
167 return current_user_can( 'edit_sc_customers' );
168 },
169 )
170 );
171
172 register_meta(
173 'user',
174 'default_password_nag',
175 array(
176 'type' => 'boolean',
177 'show_in_rest' => true,
178 'single' => true,
179 )
180 );
181 }
182
183 /**
184 * Allow querying by customer id in the REST API
185 *
186 * @param array $args Query args.
187 * @param \WP_REST_Request $request Request.
188 * @return array
189 */
190 public function userMetaQuery( $args, $request ) {
191 $key = User::getCustomerMetaKey();
192 $customer_ids = $request->get_param( 'sc_customer_ids' );
193
194 // we're only concerned about our param.
195 if ( empty( $customer_ids ) ) {
196 return $args;
197 }
198
199 // lets double-check our permissions in case other permissions fail.
200 if ( ! current_user_can( 'edit_sc_customers' ) ) {
201 return $args;
202 }
203
204 // set the meta query.
205 $args['meta_query'] = array(
206 'relation' => 'OR',
207 );
208
209 foreach ( $customer_ids as $customer_id ) {
210 $args['meta_query'][] = array(
211 'key' => $key,
212 'value' => $customer_id,
213 'compare' => 'LIKE',
214 );
215 }
216
217 return $args;
218 }
219
220 /**
221 * Query only users who are customers or not.
222 *
223 * @param array $args Query args.
224 * @param \WP_REST_Request $request Request.
225 * @return array
226 */
227 public function isCustomerQuery( $args, $request ) {
228 $is_customer = $request->get_param( 'is_customer' );
229 if ( null === $is_customer ) {
230 return $args;
231 }
232
233 if ( $is_customer ) {
234 // exists and not empty.
235 $args['meta_query'] = array(
236 'relation' => 'AND',
237 array(
238 'key' => User::getCustomerMetaKey(),
239 'compare' => 'EXISTS',
240 ),
241 array(
242 'key' => User::getCustomerMetaKey(),
243 'value' => '',
244 'compare' => '!=',
245 ),
246 );
247 } else {
248 $args['meta_query'] = array(
249 'relation' => 'OR',
250 array(
251 'key' => User::getCustomerMetaKey(),
252 'compare' => 'NOT EXISTS',
253 ),
254 array(
255 'key' => User::getCustomerMetaKey(),
256 'value' => '',
257 'compare' => '=',
258 ),
259 );
260 }
261
262 return $args;
263 }
264 }
265