PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.1
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.1
1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 All 163 releases
woocommerce-pos / includes / Services / Cashier.php

Cashier.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.1, at includes/Services/Cashier.php

223 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cashier.
4 *
5 * @package WCPOS\WooCommercePOS
6 */
7
8 namespace WCPOS\WooCommercePOS\Services;
9
10 use WCPOS\WooCommercePOS\Abstracts\Store;
11 use WCPOS\WooCommercePOS\Services\Settings\Access_Section;
12 use WCPOS\WooCommercePOS\Sync\Pos_Uuid;
13 use WP_User;
14
15 /**
16 * Cashier Service class.
17 */
18 class Cashier {
19 /**
20 * The single instance of the class.
21 *
22 * @var null|Cashier
23 */
24 private static $instance = null;
25
26 /**
27 * Constructor is private to prevent direct instantiation.
28 * Use Cashier::instance() instead.
29 */
30 private function __construct() {
31 }
32
33 /**
34 * Gets the singleton instance.
35 *
36 * @return Cashier
37 */
38 public static function instance(): self {
39 if ( null === self::$instance ) {
40 self::$instance = new self();
41 }
42
43 return self::$instance;
44 }
45
46 /**
47 * Get cashier UUID.
48 *
49 * Delegates to Pos_Uuid — the sole authority for `_woocommerce_pos_uuid` — so
50 * the /cashier endpoint and auth payloads serve the SAME identity as the
51 * /customers endpoint. The POS client keys its RxDB documents on this uuid, so
52 * a divergent value makes one person appear as two. Legacy multisite per-blog
53 * uuids (minted by an old version of this method) are adopted network-wide by
54 * the authority.
55 *
56 * @param WP_User $user User object.
57 *
58 * @return string UUID for the cashier ('' only if WooCommerce customer data is unavailable).
59 */
60 public function get_cashier_uuid( WP_User $user ): string {
61 return Pos_Uuid::ensure_user_uuid( $user );
62 }
63
64 /**
65 * Get cashier data for API responses.
66 *
67 * @param WP_User $user User object.
68 * @param bool $include_stores Whether to include stores data.
69 *
70 * @return array Cashier data.
71 */
72 public function get_cashier_data( WP_User $user, bool $include_stores = true ): array {
73 $uuid = $this->get_cashier_uuid( $user );
74 $last_access = get_user_meta( $user->ID, '_woocommerce_pos_last_access', true );
75
76 $data = array(
77 'uuid' => $uuid,
78 'id' => $user->ID,
79 'username' => $user->user_login,
80 'first_name' => $user->first_name,
81 'last_name' => $user->last_name,
82 'email' => $user->user_email,
83 'display_name' => $user->display_name,
84 'nice_name' => $user->user_nicename,
85 'roles' => array_values( $user->roles ),
86 // Raw grants (role + user), the same vocabulary the POS Access settings
87 // screen reads and writes. user_can() is wrong here: the singular meta
88 // caps (edit_product, delete_product) cannot be checked without a post.
89 'capabilities' => array_values(
90 array_filter( Access_Section::capability_names(), fn( $cap ) => ! empty( $user->allcaps[ $cap ] ) )
91 ),
92 'last_access' => $last_access ? $last_access : '',
93 'avatar_url' => get_avatar_url( $user->ID ),
94 );
95
96 if ( $include_stores ) {
97 $stores = $this->get_accessible_stores( $user );
98 $stores_data = array();
99 foreach ( $stores as $store ) {
100 $stores_data[] = $store->get_data();
101 }
102 $data['stores'] = $stores_data;
103 }
104
105 /*
106 * Filter cashier data.
107 *
108 * @param array $data Cashier data.
109 * @param WP_User $user User object.
110 * @param bool $include_stores Whether stores were included.
111 */
112 return apply_filters( 'woocommerce_pos_cashier_data', $data, $user, $include_stores );
113 }
114
115 /**
116 * Get stores accessible by the cashier.
117 *
118 * @TODO - This currently returns all stores. In the future, this should be
119 * customized based on user meta, roles, or other authorization logic to
120 * return only the stores the cashier is authorized to access.
121 *
122 * @param WP_User $user User object.
123 *
124 * @return array Array of Store objects.
125 */
126 public function get_accessible_stores( WP_User $user ): array {
127 $stores = wcpos_get_stores();
128
129 /*
130 * Filter stores accessible by cashier.
131 *
132 * @param array $stores Array of Store objects.
133 * @param WP_User $user User object.
134 */
135 return apply_filters( 'woocommerce_pos_cashier_accessible_stores', $stores, $user );
136 }
137
138 /**
139 * Check if a cashier has access to a specific store.
140 *
141 * @param WP_User $user User object.
142 * @param int $store_id Store ID.
143 *
144 * @return bool True if cashier has access, false otherwise.
145 */
146 public function has_store_access( WP_User $user, int $store_id ): bool {
147 $accessible_stores = $this->get_accessible_stores( $user );
148
149 foreach ( $accessible_stores as $store ) {
150 if ( $store->get_id() === $store_id ) {
151 return true;
152 }
153 }
154
155 return false;
156 }
157
158 /**
159 * Get a specific store for a cashier if they have access.
160 *
161 * @param WP_User $user User object.
162 * @param int $store_id Store ID.
163 *
164 * @return null|Store Store object if accessible, null otherwise.
165 */
166 public function get_accessible_store( WP_User $user, int $store_id ): ?Store {
167 $accessible_stores = $this->get_accessible_stores( $user );
168
169 foreach ( $accessible_stores as $store ) {
170 if ( $store->get_id() === $store_id ) {
171 return $store;
172 }
173 }
174
175 return null;
176 }
177
178 /**
179 * Update cashier's last access time.
180 *
181 * @param WP_User $user User object.
182 * @param string $timestamp Optional timestamp, defaults to current time.
183 *
184 * @return bool True on success, false on failure.
185 */
186 public function update_last_access( WP_User $user, string $timestamp = '' ): bool {
187 if ( empty( $timestamp ) ) {
188 $timestamp = current_time( 'mysql' );
189 }
190
191 return update_user_meta( $user->ID, '_woocommerce_pos_last_access', $timestamp );
192 }
193
194 /**
195 * Check if user has cashier permissions.
196 *
197 * @param WP_User $user User object.
198 *
199 * @return bool True if user has cashier permissions.
200 */
201 public function has_cashier_permissions( WP_User $user ): bool {
202 return user_can( $user, 'publish_shop_orders' );
203 }
204
205 /**
206 * Validate cashier access for API endpoints.
207 *
208 * @param int $current_user_id Current user ID.
209 * @param int $requested_id Requested cashier ID.
210 *
211 * @return bool True if access is allowed.
212 */
213 public function validate_cashier_access( int $current_user_id, int $requested_id ): bool {
214 // Users can access their own data.
215 if ( $current_user_id === $requested_id ) {
216 return true;
217 }
218
219 // Administrators can access any cashier data.
220 return current_user_can( 'manage_woocommerce' );
221 }
222 }
223