PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.24
Booktics – Appointment Booking Calendar for Service Businesses v1.0.24
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 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.2 1.0.3 All 31 releases
booktics / core / extensions / controllers / extension-controller.php

extension-controller.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.24, at core/extensions/controllers/extension-controller.php

274 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Booktics\Extensions\Controllers;
4
5 use Booktics\Abstracts\Base_Rest_Controller;
6 use Booktics\Extensions\Plugin_Manager;
7 use Arraytics\ToolsSdk\PluginManager as SdkPluginManager;
8 use WP_HTTP_Response;
9
10 class Extension_Controller extends Base_Rest_Controller {
11 /**
12 * Store namespace of api
13 *
14 * @var string
15 */
16 protected $namespace = 'booktics/v1';
17
18 /**
19 * Store base url
20 *
21 * @var string
22 */
23 protected $base = 'extensions';
24
25 /**
26 *
27 *
28 * @return void
29 */
30 public function register_routes(): void {
31 register_rest_route(
32 $this->namespace, $this->base, array(
33 array(
34 'methods' => \WP_REST_Server::READABLE,
35 'callback' => array( $this, 'get_items' ),
36 'permission_callback' => array(
37 $this,
38 'get_items_permissions_check',
39 ),
40 ),
41 )
42 );
43
44 register_rest_route(
45 $this->namespace, $this->base, array(
46 array(
47 'methods' => \WP_REST_Server::EDITABLE,
48 'callback' => array( $this, 'update_item' ),
49 'permission_callback' => array(
50 $this,
51 'update_item_permissions_check',
52 ),
53 ),
54 )
55 );
56 }
57
58 /**
59 * Check if a given request has access to get items
60 *
61 * @param $request
62 *
63 * @return bool|\WP_Error
64 */
65 public function get_items_permissions_check( $request ) {
66 return current_user_can( 'manage_options' );
67 }
68
69 /**
70 * Get all extensions
71 *
72 * @param $request
73 *
74 * @return WP_HTTP_Response
75 */
76 public function get_items( $request ) {
77 $type = ! empty( $request['type'] ) ? sanitize_key( $request['type'] ) : 'addon';
78
79 $extensions = array_values(
80 array_filter(
81 Plugin_Manager::extensions(),
82 function ( $extension ) use ( $type ) {
83 return $extension['type'] === $type;
84 }
85 )
86 );
87
88 $extensions = array_map(
89 function ( $extension ) {
90 $extension['status'] = 'install';
91 if ( SdkPluginManager::is_installed( $extension['slug'] ) ) {
92 $extension['status'] = 'activate';
93 }
94 if ( SdkPluginManager::is_activated( $extension['slug'] ) ) {
95 $extension['status'] = 'deactivate';
96 }
97
98 return $extension;
99 }, $extensions
100 );
101
102 return $this->response( $extensions );
103 }
104
105 /**
106 * Check if a given request has access to get items
107 *
108 * @param $request
109 *
110 * @return bool|\WP_Error
111 */
112 public function update_item_permissions_check( $request ) {
113 return current_user_can( 'manage_options' );
114 }
115
116 /**
117 * Enable or disable extension
118 *
119 * @param $request
120 *
121 * @return WP_HTTP_Response
122 */
123 public function update_item( $request ) {
124 $input_data = json_decode( $request->get_body(), true );
125 $name = $input_data['name'];
126 $status = $input_data['status'];
127
128 $statuses = array( 'off', 'on', 'install', 'activate', 'deactivate' );
129 $extensions = Plugin_Manager::extensions();
130 if ( ! $name ) {
131 return $this->error( __( 'Please enter extension name', 'booktics' ) );
132 }
133
134 if ( ! $status ) {
135 return $this->error( __( 'Please enter status', 'booktics' ) );
136 }
137
138 if ( ! in_array( $status, $statuses ) ) {
139 return $this->error( __( 'Please enter status on/off', 'booktics' ) );
140 }
141
142 if ( ! isset( $extensions[ $name ] ) ) {
143 return $this->error( __( 'Invalid extension', 'booktics' ) );
144 }
145 $extension = $extensions[ $name ];
146 if ( 'addon' === $extension['type'] ) {
147 $result = null;
148
149 if ( in_array( $status, array( 'install', 'activate' ) ) ) {
150 $result = Plugin_Manager::install_plugin( $extension['slug'] );
151 if ( $result ) {
152 $result = Plugin_Manager::activate_plugin( $extension['slug'] );
153 }
154 }
155
156 if ( 'deactivate' === $status && Plugin_Manager::is_activated( $extension['slug'] ) ) {
157 $result = Plugin_Manager::deactivate_plugin( $extension['slug'] );
158 }
159
160 if ( is_wp_error( $result ) ) {
161 return $this->error( __( 'Extension installation error', 'booktics' ) );
162 }
163
164 if ( ! $result ) {
165 // translators: %s is the action performed on the extension (install, activate, deactivate, etc.)
166 return $this->error( sprintf( __( 'Extension couldn\'t %s', 'booktics' ), $status ) );
167 }
168 }
169
170 if ( 'plugin' === $extension['type'] ) {
171 $result = null;
172
173 if ( 'install' === $status ) {
174 // Prefer the extension's own download_link (e.g. GitHub release) so a
175 // non-wordpress.org URL is not shadowed by the SDK's hardcoded wp.org zip.
176 $result = ! empty( $extension['download_link'] )
177 ? Plugin_Manager::install_plugin( $extension['slug'] )
178 : SdkPluginManager::install_plugin( $extension['slug'] );
179 if ( $result ) {
180 $result = SdkPluginManager::activate_plugin( $extension['slug'] );
181 }
182 } elseif ( 'activate' === $status ) {
183 $result = SdkPluginManager::activate_plugin( $extension['slug'] );
184 } elseif ( 'deactivate' === $status ) {
185 $result = SdkPluginManager::deactivate_plugin( $extension['slug'] );
186 }
187
188 if ( is_wp_error( $result ) ) {
189 return $this->error( __( 'Plugin operation error', 'booktics' ) );
190 }
191
192 if ( false === $result ) {
193 // translators: %s is the action performed on the plugin (install, activate, deactivate, etc.)
194 return $this->error( sprintf( __( 'Plugin couldn\'t %s', 'booktics' ), $status ) );
195 }
196 }
197
198 $response = Plugin_Manager::extensions()[ $name ];
199
200 // Nothing reaches Aisentic's provider on activation alone. The handshake only
201 // runs when the caller ticked the consent box and the plugin really is active.
202 if ( 'aisentic' === $name
203 && in_array( $status, array( 'install', 'activate' ), true )
204 && ! empty( $input_data['consent'] )
205 && SdkPluginManager::is_activated( $extension['slug'] ) ) {
206 // Snapshot before the handshake so the caller can tell a fresh
207 // registration (tokens just granted) from re-activating a site that
208 // was already connected (no new tokens).
209 $was_registered = booktics_aisentic_is_registered();
210
211 $this->register_aisentic_site();
212
213 $is_registered = booktics_aisentic_is_registered();
214
215 $response['aisentic_registered'] = $is_registered;
216
217 // True only when this request is what connected the site, so the
218 // "150K tokens added" message never fires on a plain re-activation.
219 $response['aisentic_newly_registered'] = $is_registered && ! $was_registered;
220 }
221
222 $response['status'] = 'install';
223 if ( SdkPluginManager::is_installed( $response['slug'] ) ) {
224 $response['status'] = 'activate';
225 }
226 if ( SdkPluginManager::is_activated( $response['slug'] ) ) {
227 $response['status'] = 'deactivate';
228 }
229
230 return $this->response( $response, __( 'Successfully updated', 'booktics' ) );
231 }
232
233 /**
234 * Record consent and hand the site identity to Aisentic.
235 *
236 * Only ever called from behind the consent gate in update_item(). The action is
237 * fire and forget: Aisentic owns the provider call, so a provider outage cannot
238 * fail the activation the user actually asked for.
239 *
240 * @return void
241 */
242 private function register_aisentic_site(): void {
243 // Older Aisentic builds ship no listener, so the handshake would go nowhere.
244 if ( ! class_exists( 'Aisentic\Api\Services\Registration_Service' ) ) {
245 return;
246 }
247
248 $identity = booktics_aisentic_identity();
249
250 // Fail closed. An account cannot be minted without a real address.
251 if ( empty( $identity['email'] ) ) {
252 return;
253 }
254
255 update_option(
256 'booktics_aisentic_consent', array(
257 'agreed' => true,
258 'time' => gmdate( 'c' ),
259 'user_id' => get_current_user_id(),
260 'email' => $identity['email'],
261 )
262 );
263
264 /**
265 * Fires once the admin has opted in to sharing site details with Aisentic.
266 *
267 * @param string $name Business name, falling back to the site title.
268 * @param string $email Business email, falling back to the admin email.
269 * @param string $site_url Site URL.
270 */
271 do_action( 'booktics/aisentic/register_site', $identity['name'], $identity['email'], $identity['site_url'] );
272 }
273 }
274