PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.57
Timetics – Appointment Booking Calendar & Scheduling v1.0.57
1.0.61 1.0.60 1.0.59 1.0.58 1.0.57 1.0.56 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 All 62 releases
timetics / core / addon / api-addon.php

api-addon.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.57, at core/addon/api-addon.php

241 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Addon REST API Controller
4 *
5 * @package Timetics
6 */
7
8 namespace Timetics\Core\Addon;
9
10 defined( 'ABSPATH' ) || exit;
11
12 use Timetics\Base\Api;
13 use Timetics\Utils\Singleton;
14 use Arraytics\ToolsSdk\PluginManager;
15 use WP_REST_Request;
16
17 /**
18 * Class Api_Addon
19 *
20 * Handles GET (list) and PUT (status update) for Arraytics plugins
21 * displayed on the About Us page.
22 *
23 * @since 1.0.0
24 */
25 class Api_Addon extends Api {
26
27 use Singleton;
28
29 /**
30 * REST namespace.
31 *
32 * @var string
33 */
34 protected $namespace = 'timetics/v1';
35
36 /**
37 * REST base route.
38 *
39 * @var string
40 */
41 protected $rest_base = 'addons';
42
43 /**
44 * Register REST routes.
45 *
46 * @return void
47 */
48 public function register_routes() {
49 register_rest_route(
50 $this->namespace,
51 '/' . $this->rest_base,
52 [
53 [
54 'methods' => \WP_REST_Server::READABLE,
55 'callback' => [ $this, 'get_items' ],
56 'permission_callback' => [ $this, 'get_items_permissions_check' ],
57 'args' => [
58 'type' => [
59 'description' => __( 'Filter by extension type: module, addon, plugin, or all.', 'timetics' ),
60 'type' => 'string',
61 'enum' => [ 'module', 'addon', 'plugin', 'all' ],
62 'default' => 'all',
63 ],
64 ],
65 ],
66 [
67 'methods' => \WP_REST_Server::EDITABLE,
68 'callback' => [ $this, 'update_item' ],
69 'permission_callback' => [ $this, 'update_item_permissions_check' ],
70 ],
71 ]
72 );
73 }
74
75 /**
76 * Permission check for GET.
77 *
78 * @return bool
79 */
80 public function get_items_permissions_check( $request ) {
81 return current_user_can( 'manage_options' );
82 }
83
84 /**
85 * Permission check for PUT/POST.
86 *
87 * @return bool
88 */
89 public function update_item_permissions_check( $request ) {
90 return current_user_can( 'manage_options' );
91 }
92
93 /**
94 * GET /timetics/v1/addons
95 *
96 * Returns the addon list filtered by ?type=module|addon|plugin|all.
97 *
98 * @param WP_REST_Request $request
99 * @return \WP_REST_Response
100 */
101 public function get_items( $request ) {
102 $type = ! empty( $request['type'] ) ? sanitize_key( $request['type'] ) : 'all';
103 $extensions = timetics_extension();
104
105 $type_map = [
106 'module' => [ $extensions, 'get_modules' ],
107 'addon' => [ $extensions, 'get_addons' ],
108 'plugin' => [ $extensions, 'get_plugins' ],
109 'all' => [ $extensions, 'get' ],
110 ];
111
112 if ( ! isset( $type_map[ $type ] ) ) {
113 return $this->send_error(
114 __( 'Invalid extension type.', 'timetics' ),
115 [ 'status' => 400 ]
116 );
117 }
118
119 $items = array_values( call_user_func( $type_map[ $type ] ) );
120
121 return rest_ensure_response(
122 [
123 'success' => true,
124 'data' => $items,
125 ]
126 );
127 }
128
129 /**
130 * PUT /timetics/v1/addons
131 *
132 * Updates the status of an Arraytics plugin (install/activate/deactivate/upgrade).
133 *
134 * @param WP_REST_Request $request
135 * @return \WP_REST_Response
136 */
137 public function update_item( $request ) {
138 $params = json_decode( $request->get_body(), true );
139
140 $name = isset( $params['name'] ) ? sanitize_text_field( $params['name'] ) : '';
141 $status = isset( $params['status'] ) ? sanitize_text_field( $params['status'] ) : '';
142
143 $valid_statuses = [ 'install', 'activate', 'deactivate', 'upgrade' ];
144
145 if ( empty( $name ) ) {
146 return $this->send_error(
147 __( 'Please enter an extension name.', 'timetics' ),
148 [ 'status' => 422 ]
149 );
150 }
151
152 if ( empty( $status ) || ! in_array( $status, $valid_statuses, true ) ) {
153 return $this->send_error(
154 /* translators: %s: status value */
155 sprintf( __( 'Invalid status "%s" provided.', 'timetics' ), $status ),
156 [ 'status' => 422 ]
157 );
158 }
159
160 $extension = timetics_extension()->find( $name );
161
162 if ( ! $extension ) {
163 return $this->send_error(
164 /* translators: %s: plugin name */
165 sprintf( __( 'Extension "%s" not found.', 'timetics' ), $name ),
166 [ 'status' => 404 ]
167 );
168 }
169
170 // Redirect for upgrade (premium) actions.
171 if ( 'upgrade' === $status ) {
172 return rest_ensure_response(
173 [
174 'success' => true,
175 'data' => [ 'redirect_url' => $extension['upgrade_link'] ],
176 'message' => __( 'Redirecting to upgrade page.', 'timetics' ),
177 ]
178 );
179 }
180
181 // All registered extensions are type=plugin — delegate to PluginManager.
182 $slug = isset( $extension['slug'] ) ? $extension['slug'] : $name;
183
184 switch ( $status ) {
185 case 'install':
186 if ( ! function_exists( 'WP_Filesystem' ) ) {
187 require_once ABSPATH . 'wp-admin/includes/file.php';
188 }
189 WP_Filesystem();
190 $result = PluginManager::install_plugin( $slug );
191 break;
192 case 'activate':
193 $result = PluginManager::activate_plugin( $slug );
194 break;
195 case 'deactivate':
196 $result = PluginManager::deactivate_plugin( $slug );
197 break;
198 default:
199 $result = false;
200 }
201
202 if ( false === $result || is_wp_error( $result ) ) {
203 $message = is_wp_error( $result )
204 ? $result->get_error_message()
205 /* translators: %s: action name */
206 : sprintf( __( 'Could not %s the extension.', 'timetics' ), $status );
207
208 return $this->send_error( $message, [ 'status' => 500 ] );
209 }
210
211 return rest_ensure_response(
212 [
213 'success' => true,
214 'data' => [
215 'name' => $name,
216 'status' => $status,
217 ],
218 /* translators: %s: action name */
219 'message' => sprintf( __( 'Extension %s successfully.', 'timetics' ), $status . 'd' ),
220 ]
221 );
222 }
223
224 /**
225 * Return a standardised error response.
226 *
227 * @param string $message Human-readable error message.
228 * @param array $data Additional data (e.g. ['status' => 422]).
229 * @return \WP_REST_Response
230 */
231 private function send_error( string $message, array $data = [] ): \WP_REST_Response {
232 return rest_ensure_response(
233 [
234 'success' => false,
235 'message' => $message,
236 'data' => $data,
237 ]
238 );
239 }
240 }
241