Skip to content

Commit 54a8e88

Browse files
committed
add template editor
1 parent 60f3c28 commit 54a8e88

File tree

12 files changed

+1884
-133
lines changed

12 files changed

+1884
-133
lines changed

includes/API.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public function register_routes(): void {
8989
'auth' => API\Auth::class,
9090
'settings' => API\Settings::class,
9191
'cashier' => API\Cashier::class,
92+
'templates' => API\Templates_Controller::class,
9293

9394
// extend WC REST API controllers.
9495
'products' => API\Products_Controller::class,
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
<?php
2+
3+
namespace WCPOS\WooCommercePOS\API;
4+
5+
use const WCPOS\WooCommercePOS\SHORT_NAME;
6+
use WCPOS\WooCommercePOS\Templates as TemplatesManager;
7+
use WP_Error;
8+
use WP_Query;
9+
use WP_REST_Controller;
10+
use WP_REST_Request;
11+
use WP_REST_Response;
12+
use WP_REST_Server;
13+
14+
/**
15+
* Class Templates REST API Controller.
16+
*/
17+
class Templates_Controller extends WP_REST_Controller {
18+
/**
19+
* Endpoint namespace.
20+
*
21+
* @var string
22+
*/
23+
protected $namespace = SHORT_NAME . '/v1';
24+
25+
/**
26+
* Route base.
27+
*
28+
* @var string
29+
*/
30+
protected $rest_base = 'templates';
31+
32+
/**
33+
* Register routes.
34+
*
35+
* @return void
36+
*/
37+
public function register_routes(): void {
38+
// List all templates
39+
register_rest_route(
40+
$this->namespace,
41+
'/' . $this->rest_base,
42+
array(
43+
'methods' => WP_REST_Server::READABLE,
44+
'callback' => array( $this, 'get_items' ),
45+
'permission_callback' => array( $this, 'get_items_permissions_check' ),
46+
'args' => $this->get_collection_params(),
47+
)
48+
);
49+
50+
// Get single template
51+
register_rest_route(
52+
$this->namespace,
53+
'/' . $this->rest_base . '/(?P<id>[\d]+)',
54+
array(
55+
'methods' => WP_REST_Server::READABLE,
56+
'callback' => array( $this, 'get_item' ),
57+
'permission_callback' => array( $this, 'get_item_permissions_check' ),
58+
'args' => array(
59+
'id' => array(
60+
'description' => __( 'Unique identifier for the template.', 'woocommerce-pos' ),
61+
'type' => 'integer',
62+
'required' => true,
63+
),
64+
),
65+
)
66+
);
67+
}
68+
69+
/**
70+
* Get a collection of templates.
71+
*
72+
* @param WP_REST_Request $request Full details about the request.
73+
*
74+
* @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
75+
*/
76+
public function get_items( $request ) {
77+
$args = array(
78+
'post_type' => 'wcpos_template',
79+
'post_status' => 'publish',
80+
'posts_per_page' => $request->get_param( 'per_page' ) ?? -1,
81+
'paged' => $request->get_param( 'page' ) ?? 1,
82+
);
83+
84+
// Filter by template type
85+
$type = $request->get_param( 'type' );
86+
if ( $type ) {
87+
$args['tax_query'] = array(
88+
array(
89+
'taxonomy' => 'wcpos_template_type',
90+
'field' => 'slug',
91+
'terms' => $type,
92+
),
93+
);
94+
}
95+
96+
$query = new WP_Query( $args );
97+
$templates = array();
98+
99+
foreach ( $query->posts as $post ) {
100+
$template = TemplatesManager::get_template( $post->ID );
101+
if ( $template ) {
102+
$templates[] = $this->prepare_item_for_response( $template, $request );
103+
}
104+
}
105+
106+
$response = rest_ensure_response( $templates );
107+
$response->header( 'X-WP-Total', $query->found_posts );
108+
$response->header( 'X-WP-TotalPages', $query->max_num_pages );
109+
110+
return $response;
111+
}
112+
113+
/**
114+
* Get a single template.
115+
*
116+
* @param WP_REST_Request $request Full details about the request.
117+
*
118+
* @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
119+
*/
120+
public function get_item( $request ) {
121+
$id = (int) $request['id'];
122+
$template = TemplatesManager::get_template( $id );
123+
124+
if ( ! $template ) {
125+
return new WP_Error(
126+
'wcpos_template_invalid_id',
127+
__( 'Invalid template ID.', 'woocommerce-pos' ),
128+
array( 'status' => 404 )
129+
);
130+
}
131+
132+
return rest_ensure_response( $this->prepare_item_for_response( $template, $request ) );
133+
}
134+
135+
/**
136+
* Prepare template for response.
137+
*
138+
* @param array $template Template data.
139+
* @param WP_REST_Request $request Request object.
140+
*
141+
* @return array Prepared template data.
142+
*/
143+
public function prepare_item_for_response( $template, $request ) {
144+
return $template;
145+
}
146+
147+
/**
148+
* Get collection parameters.
149+
*
150+
* @return array Collection parameters.
151+
*/
152+
public function get_collection_params() {
153+
return array(
154+
'page' => array(
155+
'description' => __( 'Current page of the collection.', 'woocommerce-pos' ),
156+
'type' => 'integer',
157+
'default' => 1,
158+
'sanitize_callback' => 'absint',
159+
'validate_callback' => 'rest_validate_request_arg',
160+
),
161+
'per_page' => array(
162+
'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-pos' ),
163+
'type' => 'integer',
164+
'default' => -1,
165+
'sanitize_callback' => 'absint',
166+
'validate_callback' => 'rest_validate_request_arg',
167+
),
168+
'type' => array(
169+
'description' => __( 'Filter by template type.', 'woocommerce-pos' ),
170+
'type' => 'string',
171+
'enum' => array( 'receipt', 'report' ),
172+
'sanitize_callback' => 'sanitize_text_field',
173+
'validate_callback' => 'rest_validate_request_arg',
174+
),
175+
);
176+
}
177+
178+
/**
179+
* Check if a given request has access to read templates.
180+
*
181+
* @param WP_REST_Request $request Full details about the request.
182+
*
183+
* @return bool|WP_Error True if the request has access, WP_Error object otherwise.
184+
*/
185+
public function get_items_permissions_check( $request ) {
186+
if ( ! current_user_can( 'manage_woocommerce_pos' ) ) {
187+
return new WP_Error(
188+
'wcpos_rest_cannot_view',
189+
__( 'Sorry, you cannot list templates.', 'woocommerce-pos' ),
190+
array( 'status' => rest_authorization_required_code() )
191+
);
192+
}
193+
194+
return true;
195+
}
196+
197+
/**
198+
* Check if a given request has access to read a specific template.
199+
*
200+
* @param WP_REST_Request $request Full details about the request.
201+
*
202+
* @return bool|WP_Error True if the request has access, WP_Error object otherwise.
203+
*/
204+
public function get_item_permissions_check( $request ) {
205+
if ( ! current_user_can( 'manage_woocommerce_pos' ) ) {
206+
return new WP_Error(
207+
'wcpos_rest_cannot_view',
208+
__( 'Sorry, you cannot view this template.', 'woocommerce-pos' ),
209+
array( 'status' => rest_authorization_required_code() )
210+
);
211+
}
212+
213+
return true;
214+
}
215+
}

includes/Admin.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public function __construct() {
7878
public function init(): void {
7979
new Notices();
8080
new Pro_Plugin_Updater();
81+
new Admin\Templates();
8182
}
8283

8384
/**

includes/Admin/Menu.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ private function register_pos_admin(): void {
145145
array( '\WCPOS\WooCommercePOS\Admin\Settings', 'display_settings_page' )
146146
);
147147

148+
add_submenu_page(
149+
PLUGIN_NAME,
150+
__( 'Templates', 'woocommerce-pos' ),
151+
__( 'Templates', 'woocommerce-pos' ),
152+
'manage_woocommerce_pos',
153+
'edit.php?post_type=wcpos_template'
154+
);
155+
148156
// adjust submenu
149157
global $submenu;
150158
$pos_submenu = &$submenu[ PLUGIN_NAME ];

0 commit comments

Comments
 (0)