PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.17
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.17
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 1.9.13 All 162 releases
woocommerce-pos / includes / API / V1 / Cashier.php

Cashier.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.17, at includes/API/V1/Cashier.php

305 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cashier API.
4 *
5 * @package WCPOS\WooCommercePOS
6 */
7
8 namespace WCPOS\WooCommercePOS\API\V1;
9
10 \defined( 'ABSPATH' ) || die;
11
12 if ( ! class_exists( 'WP_REST_Controller' ) ) {
13 return;
14 }
15
16 use Exception;
17 use WCPOS\WooCommercePOS\Abstracts\Store;
18 use WCPOS\WooCommercePOS\Services\Cashier as CashierService;
19 use const WCPOS\WooCommercePOS\SHORT_NAME;
20 use WP_Error;
21 use WP_REST_Controller;
22 use WP_REST_Request;
23 use WP_REST_Response;
24 use WP_REST_Server;
25 use WP_User;
26
27 /**
28 * Cashier API Controller.
29 */
30 class Cashier extends WP_REST_Controller {
31 /**
32 * Endpoint namespace.
33 *
34 * @var string
35 */
36 protected $namespace = SHORT_NAME . '/v1';
37
38 /**
39 * Route base.
40 *
41 * @var string
42 */
43 protected $rest_base = 'cashier';
44
45 /**
46 * Register the routes for the cashier controller.
47 */
48 public function register_routes(): void {
49 // Get cashier data: /wcpos/v1/cashier/{id}.
50 register_rest_route(
51 $this->namespace,
52 '/' . $this->rest_base . '/(?P<id>[\d]+)',
53 array(
54 'methods' => WP_REST_Server::READABLE,
55 'callback' => array( $this, 'get_cashier' ),
56 'permission_callback' => array( $this, 'check_cashier_permissions' ),
57 'args' => array(
58 'id' => array(
59 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ),
60 'type' => 'integer',
61 'required' => true,
62 ),
63 ),
64 )
65 );
66
67 // Get cashier stores: /wcpos/v1/cashier/{id}/stores.
68 register_rest_route(
69 $this->namespace,
70 '/' . $this->rest_base . '/(?P<id>[\d]+)/stores',
71 array(
72 'methods' => WP_REST_Server::READABLE,
73 'callback' => array( $this, 'get_cashier_stores' ),
74 'permission_callback' => array( $this, 'check_cashier_permissions' ),
75 'args' => array(
76 'id' => array(
77 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ),
78 'type' => 'integer',
79 'required' => true,
80 ),
81 ),
82 )
83 );
84
85 // Get specific store for cashier: /wcpos/v1/cashier/{id}/stores/{store_id}.
86 register_rest_route(
87 $this->namespace,
88 '/' . $this->rest_base . '/(?P<id>[\d]+)/stores/(?P<store_id>[\d]+)',
89 array(
90 'methods' => WP_REST_Server::READABLE,
91 'callback' => array( $this, 'get_cashier_store' ),
92 'permission_callback' => array( $this, 'check_cashier_permissions' ),
93 'args' => array(
94 'id' => array(
95 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ),
96 'type' => 'integer',
97 'required' => true,
98 ),
99 'store_id' => array(
100 'description' => __( 'Unique identifier for the store.', 'woocommerce-pos' ),
101 'type' => 'integer',
102 'required' => true,
103 ),
104 ),
105 )
106 );
107 }
108
109 /**
110 * Check permissions for cashier endpoints.
111 *
112 * Ensures the user is authenticated and can only access their own data.
113 *
114 * @param WP_REST_Request $request The REST request object.
115 *
116 * @return bool|WP_Error True if authorized, WP_Error otherwise.
117 */
118 public function check_cashier_permissions( WP_REST_Request $request ) {
119 // Check if user is authenticated.
120 if ( ! is_user_logged_in() ) {
121 return new WP_Error(
122 'woocommerce_pos_rest_unauthorized',
123 /* translators: REST API schema field label or error message. */
124 __( 'Authentication required.', 'woocommerce-pos' ),
125 array( 'status' => 401 )
126 );
127 }
128
129 $current_user_id = get_current_user_id();
130 $requested_id = (int) $request->get_param( 'id' );
131
132 // Check if the requested user exists.
133 $user = get_user_by( 'id', $requested_id );
134 if ( ! $user ) {
135 return new WP_Error(
136 'woocommerce_pos_cashier_not_found',
137 /* translators: REST API schema field label or error message. */
138 __( 'Cashier not found.', 'woocommerce-pos' ),
139 array( 'status' => 404 )
140 );
141 }
142
143 $cashier_service = CashierService::instance();
144
145 // Check if user has POS cashier permissions.
146 if ( ! $cashier_service->has_cashier_permissions( $user ) ) {
147 return new WP_Error(
148 'woocommerce_pos_rest_forbidden',
149 __( 'User does not have POS cashier permissions.', 'woocommerce-pos' ),
150 array( 'status' => 403 )
151 );
152 }
153
154 // Validate access permissions.
155 if ( ! $cashier_service->validate_cashier_access( $current_user_id, $requested_id ) ) {
156 return new WP_Error(
157 'woocommerce_pos_rest_forbidden',
158 __( 'You can only access your own cashier data.', 'woocommerce-pos' ),
159 array( 'status' => 403 )
160 );
161 }
162
163 return true;
164 }
165
166 /**
167 * Get cashier data.
168 *
169 * @param WP_REST_Request $request The REST request object.
170 *
171 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
172 */
173 public function get_cashier( WP_REST_Request $request ) {
174 $user_id = (int) $request->get_param( 'id' );
175 $user = get_user_by( 'id', $user_id );
176
177 if ( ! $user ) {
178 return new WP_Error(
179 'woocommerce_pos_cashier_not_found',
180 /* translators: REST API schema field label or error message. */
181 __( 'Cashier not found.', 'woocommerce-pos' ),
182 array( 'status' => 404 )
183 );
184 }
185
186 $cashier_service = CashierService::instance();
187 $data = $cashier_service->get_cashier_data( $user, true );
188
189 /**
190 * Filter cashier data for REST API response.
191 *
192 * @param array $data Cashier data.
193 * @param WP_User $user User object.
194 * @param WP_REST_Request $request Request object.
195 */
196 $data = apply_filters( 'woocommerce_pos_rest_prepare_cashier', $data, $user, $request );
197
198 return rest_ensure_response( $data );
199 }
200
201 /**
202 * Get stores accessible by the cashier.
203 *
204 * @param WP_REST_Request $request The REST request object.
205 *
206 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
207 */
208 public function get_cashier_stores( WP_REST_Request $request ) {
209 $user_id = (int) $request->get_param( 'id' );
210 $user = get_user_by( 'id', $user_id );
211
212 if ( ! $user ) {
213 return new WP_Error(
214 'woocommerce_pos_cashier_not_found',
215 /* translators: REST API schema field label or error message. */
216 __( 'Cashier not found.', 'woocommerce-pos' ),
217 array( 'status' => 404 )
218 );
219 }
220
221 try {
222 $cashier_service = CashierService::instance();
223 $stores = $cashier_service->get_accessible_stores( $user );
224 $response = array();
225
226 foreach ( $stores as $store ) {
227 $data = $this->prepare_store_for_response( $store, $request );
228 $response[] = $data;
229 }
230
231 $response = rest_ensure_response( $response );
232 $response->header( 'X-WP-Total', (string) \count( $stores ) );
233 $response->header( 'X-WP-TotalPages', '1' );
234
235 return $response;
236 } catch ( Exception $e ) {
237 return new WP_Error(
238 'woocommerce_pos_stores_retrieval_failed',
239 __( 'Failed to retrieve store data.', 'woocommerce-pos' ),
240 array( 'status' => 500 )
241 );
242 }
243 }
244
245 /**
246 * Get a specific store for the cashier.
247 *
248 * @param WP_REST_Request $request The REST request object.
249 *
250 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
251 */
252 public function get_cashier_store( WP_REST_Request $request ) {
253 $user_id = (int) $request->get_param( 'id' );
254 $store_id = (int) $request->get_param( 'store_id' );
255
256 $user = get_user_by( 'id', $user_id );
257 if ( ! $user ) {
258 return new WP_Error(
259 'woocommerce_pos_cashier_not_found',
260 /* translators: REST API schema field label or error message. */
261 __( 'Cashier not found.', 'woocommerce-pos' ),
262 array( 'status' => 404 )
263 );
264 }
265
266 $cashier_service = CashierService::instance();
267 $store = $cashier_service->get_accessible_store( $user, $store_id );
268
269 if ( ! $store ) {
270 return new WP_Error(
271 'woocommerce_pos_store_not_found',
272 __( 'Store not found or not accessible by this cashier.', 'woocommerce-pos' ),
273 array( 'status' => 404 )
274 );
275 }
276
277 $data = $this->prepare_store_for_response( $store, $request );
278
279 return rest_ensure_response( $data );
280 }
281
282
283
284 /**
285 * Prepare store data for response.
286 *
287 * @param Store $store Store object.
288 * @param WP_REST_Request $request Request object.
289 *
290 * @return array Prepared store data.
291 */
292 protected function prepare_store_for_response( Store $store, WP_REST_Request $request ): array {
293 $data = $store->get_data();
294
295 /*
296 * Filter store data for REST API response.
297 *
298 * @param array $data Store data.
299 * @param Store $store Store object.
300 * @param WP_REST_Request $request Request object.
301 */
302 return apply_filters( 'woocommerce_pos_rest_prepare_store', $data, $store, $request );
303 }
304 }
305