PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.4.16
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.4.16
1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 1.3.49 1.3.48 1.3.47 All 179 releases
disco / rest / Analytics / OrdersApi.php

OrdersApi.php in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.4.16, at rest/Analytics/OrdersApi.php

203 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php //phpcs:ignore
2
3 /**
4 * Analytics REST API — Orders Endpoints
5 *
6 * @package Disco
7 * @subpackage \Rest\Analytics
8 * @since 1.1.13
9 * @category Rest
10 */
11
12 namespace Disco\Rest\Analytics;
13
14 use Disco\App\Analytics\Services\OrderService;
15 use WP_REST_Server;
16
17 /**
18 * Class OrdersApi
19 *
20 * Registers and handles the following REST API routes:
21 *
22 * - GET /disco/v1/analytics/orders — Paginated campaign-linked orders.
23 * - GET /disco/v1/analytics/orders/{id} — Single order with full line items.
24 *
25 * @package Disco
26 * @subpackage \Rest\Analytics
27 * @author Ohidul Islam <wahid0003@gmail.com>
28 * @link https://webappick.com
29 * @license https://opensource.org/licenses/gpl-license.php GNU Public License
30 * @category Rest
31 */
32 class OrdersApi extends Base {
33
34 /**
35 * Registers the REST API routes for orders analytics endpoints.
36 */
37 public function register_routes(): void {
38 // GET /analytics/orders
39 register_rest_route(
40 $this->namespace,
41 '/' . $this->rest_base . '/orders',
42 array(
43 array(
44 'methods' => WP_REST_Server::READABLE,
45 'callback' => array( $this, 'get_orders' ),
46 'permission_callback' => array( $this, 'permissions_check' ),
47 'args' => $this->get_orders_table_params(),
48 ),
49 'schema' => array( $this, 'get_order_schema' ),
50 )
51 );
52
53 // GET /analytics/orders/{id}
54 register_rest_route(
55 $this->namespace,
56 '/' . $this->rest_base . '/orders/(?P<id>[\d]+)',
57 array(
58 'args' => array(
59 'id' => array(
60 'description' => __( 'WooCommerce Order ID.', 'disco' ),
61 'type' => 'integer',
62 ),
63 ),
64 array(
65 'methods' => WP_REST_Server::READABLE,
66 'callback' => array( $this, 'get_order' ),
67 'permission_callback' => array( $this, 'permissions_check' ),
68 ),
69 'schema' => array( $this, 'get_order_schema' ),
70 )
71 );
72 }
73
74 // =========================================================================
75 // Callbacks
76 // =========================================================================
77
78 /**
79 * GET /disco/v1/analytics/orders
80 *
81 * Returns a paginated list of completed, Disco-driven orders.
82 * Only orders with a disco_campaign meta are included.
83 *
84 * Query params:
85 * date_from (string Y-m-d) Range start. Default: 28 days ago.
86 * date_to (string Y-m-d) Range end. Default: today.
87 * search (string) Numeric = exact order ID; text = customer name/email LIKE search.
88 * sort_by (string) Alias for orderby. One of: revenue (default), date, quantity.
89 * orderby (string) Sort field. One of: revenue (default), date, quantity.
90 * order (string) Sort direction: asc | desc (default).
91 * campaign_id (int) Filter to orders that used this campaign.
92 * customer_id (int) Filter to orders by this WP user.
93 * page (int ≥ 1) Page number. Default: 1.
94 * limit (int 1–100) Results per page. Default: 10.
95 *
96 * @param \WP_REST_Request $request Incoming REST request.
97 * @return \WP_REST_Response|\WP_Error
98 */
99 // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh, SlevomatCodingStandard.Functions.FunctionLength.FunctionLength
100 public function get_orders( $request ) {
101 $error = $this->validate_date_params( $request );
102
103 if ( is_wp_error( $error ) ) {
104 return $error;
105 }
106
107 $page = 1;
108 $per_page = 10;
109
110 if ( isset( $request['page'] ) ) {
111 $page = absint( $request['page'] );
112 }
113
114 if ( isset( $request['limit'] ) ) {
115 $per_page = min( absint( $request['limit'] ), 100 );
116 }
117
118 $sort_by_map = array(
119 'revenue' => 'revenue',
120 'date' => 'date',
121 'quantity' => 'quantity',
122 );
123 $sort_by = '';
124 $default_orderby = 'revenue';
125
126 if ( is_string( $request['sort_by'] ) ) {
127 $sort_by = sanitize_text_field( $request['sort_by'] );
128 }
129
130 if ( is_string( $request['orderby'] ) ) {
131 $default_orderby = sanitize_text_field( $request['orderby'] );
132 }
133
134 $orderby = $sort_by_map[ $sort_by ] ?? $default_orderby;
135
136 $date_to = gmdate( 'Y-m-d' );
137
138 if ( is_string( $request['date_to'] ) && $request['date_to'] ) {
139 $date_to = sanitize_text_field( $request['date_to'] );
140 }
141
142 $date_from = gmdate( 'Y-m-d', strtotime( '-27 days', (int) strtotime( $date_to ) ) );
143
144 if ( is_string( $request['date_from'] ) && $request['date_from'] ) {
145 $date_from = sanitize_text_field( $request['date_from'] );
146 }
147
148 $args = array(
149 'date_from' => $date_from,
150 'date_to' => $date_to,
151 'search' => is_string( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '',
152 'campaign_id' => isset( $request['campaign_id'] ) ? absint( $request['campaign_id'] ) : 0,
153 'customer_id' => isset( $request['customer_id'] ) ? absint( $request['customer_id'] ) : 0,
154 'orderby' => $orderby,
155 'order' => is_string( $request['order'] ) ? sanitize_text_field( $request['order'] ) : 'desc',
156 'page' => $page,
157 'limit' => $per_page,
158 );
159
160 $result = OrderService::get_orders_table( $args );
161 $pagination = $result['pagination'];
162 $total = (int) ( $pagination['total'] ?? 0 );
163 $total_pages = (int) ( $pagination['pages'] ?? 0 );
164
165 $response_data = array(
166 'current_period' => $result['current_period'],
167 'compare_period' => $result['compare_period'],
168 'data' => $this->add_item_links( $result['data'], 'orders' ),
169 'collection' => $this->build_collection_meta( $total, $per_page, $page ),
170 'links' => $this->build_top_links( $request, 'orders', $total_pages, $page ),
171 );
172
173 $response = rest_ensure_response( $response_data );
174 $response->header( 'X-WP-Total', $total );
175 $response->header( 'X-WP-TotalPages', $total_pages );
176
177 return $response;
178 }
179
180 /**
181 * GET /disco/v1/analytics/orders/{id}
182 *
183 * Returns the full detail for a single campaign-linked order, including all
184 * line items with per-item discount amounts.
185 *
186 * Path param:
187 * id (int) WooCommerce order ID.
188 *
189 * @param \WP_REST_Request $request Incoming REST request.
190 * @return \WP_REST_Response|\WP_Error
191 */
192 public function get_order( $request ) {
193 $data = OrderService::get_order( absint( $request['id'] ) );
194
195 if ( is_wp_error( $data ) ) {
196 return $data;
197 }
198
199 return rest_ensure_response( $data );
200 }
201
202 }
203