PluginProbe
Media Cloud Sync / trunk
Media Cloud Sync vtrunk
1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 All 34 releases
media-cloud-sync / includes / api.php

api.php in Media Cloud Sync trunk, at includes/api.php

723 lines 22.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Dudlewebs\WPMCS;
3
4 use WP_REST_Response;
5
6 defined('ABSPATH') || exit;
7
8 class Api {
9 private static $instance = null;
10 private $token;
11 private $version;
12 private $assets_url;
13
14 /**
15 * Constructor
16 * @since 1.0.0
17 */
18
19 public function __construct() {
20 $this->assets_url = WPMCS_ASSETS_URL;
21 $this->version = WPMCS_VERSION;
22 $this->token = WPMCS_TOKEN;
23
24 add_action( 'rest_api_init', array( $this, 'register_routes' ) );
25 }
26
27
28 /**
29 * Register API routes
30 */
31
32 public function register_routes() {
33 $this->add_route( '/verifyCredentials', 'verifyCredentials', 'POST' );
34 $this->add_route( '/bucket/checkExist', 'verifyBucketExist', 'POST' );
35 $this->add_route( '/bucket/addNew', 'createBucket', 'POST' );
36 $this->add_route( '/permissions/status', 'verifyStatus', 'POST' );
37 $this->add_route( '/permissions/write', 'verifyWrite', 'POST' );
38 $this->add_route( '/permissions/delete', 'verifyObjectDelete', 'POST' );
39 $this->add_route( '/permissions/read', 'verifyRead', 'POST' );
40
41 $this->add_route( '/security/get_security', 'getBucketSecuritySettings', 'POST' );
42 $this->add_route( '/security/block_public_access', 'changePublicAccess', 'POST' );
43 $this->add_route( '/security/object_ownership_enforce', 'changeObjectOwnership', 'POST' );
44
45 $this->add_route( '/getSettings', 'getSettings' );
46 $this->add_route( '/saveConfig', 'saveConfig', 'POST' );
47 $this->add_route( '/refreshCounts', 'refreshCounts', 'POST' );
48 $this->add_route( '/getErrorLogs', 'getErrorLogs', 'POST' );
49 $this->add_route( '/clearErrorLogs', 'clearErrorLogs', 'POST' );
50
51 // Upgrade Database Routes
52 $this->add_route( '/upgrade/status', 'getUpgradeStatus' );
53 $this->add_route( '/upgrade/start', 'startUpgrade', 'POST' );
54
55 // Sync Routes
56 $this->add_route( '/sync/status', 'getStatus' );
57 $this->add_route( '/sync/start', 'startSync', 'POST' );
58 $this->add_route( '/sync/pause', 'pauseSync', 'POST' );
59 $this->add_route( '/sync/resume', 'resumeSync', 'POST' );
60 $this->add_route( '/sync/stop', 'stopSync', 'POST' );
61 $this->add_route( '/sync/tick', 'tickSync', 'POST' );
62 $this->add_route( '/sync/setMethod', 'setSyncMethod', 'POST' );
63
64 $this->add_route( '/sync/retrySingle', 'retrySingle', 'POST' );
65 }
66
67 /**
68 * Verify the Service Credentials
69 */
70 public function verifyCredentials( $data ) {
71 return new WP_REST_Response( Service::instance()->verifyCredentials($data->get_params()), 200 );
72 }
73
74 /**
75 * Verify the Bucket exist
76 */
77 public function verifyBucketExist( $data ) {
78 return new WP_REST_Response( Service::instance()->verifyBucketExist($data->get_params()), 200 );
79 }
80
81 /**
82 * Create the bucket
83 */
84 public function createBucket( $data ) {
85 return new WP_REST_Response( Service::instance()->createBucket($data->get_params()), 200 );
86 }
87
88 /**
89 * Saved connection status checks (storage, CDN).
90 * @since 1.3.11
91 */
92 public function verifyStatus( $data ) {
93 $params = $data->get_params();
94 $check = isset( $params['check'] ) ? sanitize_text_field( $params['check'] ) : 'storage';
95 return new WP_REST_Response( Service::instance()->verifyStatus( $check ), 200 );
96 }
97
98 /**
99 * Verify bucket write permission (configure wizard) or saved storage status (legacy route).
100 * @since 1.3.11
101 */
102 public function verifyWrite( $data ) {
103 $params = $data->get_params();
104 if ( !empty( $params['service'] ) ) {
105 return new WP_REST_Response( Service::instance()->verifyObjectWritePermission( $params ), 200 );
106 }
107 return new WP_REST_Response( Service::instance()->verifyStatus( 'storage' ), 200 );
108 }
109
110 /**
111 * Verify the Bucket delete Permission
112 */
113 public function verifyObjectDelete( $data ) {
114 return new WP_REST_Response( Service::instance()->verifyObjectDeletePermission($data->get_params()), 200 );
115 }
116
117 /**
118 * Verify delivery read access (legacy route).
119 * @since 1.3.11
120 */
121 public function verifyRead( $data ) {
122 return new WP_REST_Response( Service::instance()->verifyStatus( 'cdn' ), 200 );
123 }
124
125 /**
126 * Get the Security Settings
127 */
128 public function getBucketSecuritySettings( $data ) {
129 return new WP_REST_Response( Service::instance()->getBucketSecuritySettings($data->get_params()), 200 );
130 }
131
132
133 /**
134 * Change the Public Access
135 */
136 public function changePublicAccess( $data ) {
137 return new WP_REST_Response( Service::instance()->changePublicAccess($data->get_params()), 200 );
138 }
139
140
141 /**
142 * Change the Object Ownership
143 */
144 public function changeObjectOwnership( $data ) {
145 return new WP_REST_Response( Service::instance()->changeObjectOwnership($data->get_params()), 200 );
146 }
147
148 /**
149 * Get Settings
150 */
151 public function getSettings( ) {
152 // Fetch and update media counts for make sure they are up to date
153 Counter::fetch_and_update();
154
155 $data = [
156 'credentials' => Utils::get_credentials( '', [], true ),
157 'serviceEnabled' => Utils::is_service_enabled(),
158 'serviceError' => Utils::get_service_configuration_error(),
159 'common' => [
160 'version' => defined('WPMCS_PRO_VERSION') ? WPMCS_PRO_VERSION : WPMCS_VERSION,
161 'counts' => [
162 'all' => Counter::get_count(),
163 'categorized' => $this->getSortedMediaCounts()
164 ],
165 'status' => Utils::get_status('', false),
166 'settings' => Utils::get_settings(),
167 ],
168 'sync' => Sync::instance()->get_status(),
169 'license' => defined('WPMCS_PRO_VERSION') ? Utils::get_safe_license_data() : [],
170 'file_manager' => defined('WPMCS_PRO_VERSION') ? [
171 'delete_enabled' => (bool) Utils::get_option('delete_enabled', false, Schema::getConstant('FILE_MANAGER_SETTINGS_KEY')),
172 'root_folder' => Utils::get_option('root_folder', '', Schema::getConstant('FILE_MANAGER_SETTINGS_KEY')),
173 ] : [],
174 ];
175
176 return new WP_REST_Response( $data, 200 );
177 }
178
179 /**
180 * Save the Configurations
181 */
182 public function saveConfig( $data ) {
183 $saveData = $data->get_params();
184 $result = [
185 'success' => false,
186 'message' => esc_html__('Something went wrong. Invalid data recieved', 'media-cloud-sync')
187 ];
188
189 $action = isset($saveData['action']) ? $saveData['action'] : false;
190 if($action === false) return new WP_REST_Response( $result, 200 );
191
192 $service = isset($saveData['service']) ? $saveData['service'] : false;
193 $serviceLabel = isset($saveData['serviceLabel']) ? $saveData['serviceLabel'] : '';
194 $cdn = isset($saveData['cdn']) ? $saveData['cdn'] : [];
195 $config = isset($saveData['config']) ? $saveData['config'] : false;
196 $configSource = isset($saveData['configSource']) ? $saveData['configSource'] : 'database';
197 $bucketConfig = isset($saveData['bucketConfig']) ? $saveData['bucketConfig'] : [];
198 $security = isset($saveData['security']) ? $saveData['security'] : [];
199 $settings = isset($saveData['settings']) ? $saveData['settings'] : [];
200
201 $serviceOk = true;
202 $settingsOk = true;
203
204 if( $action === 'cdn' ){
205 $existing = Utils::get_credentials();
206 $existing['cdn'] = $cdn;
207
208 $updated = Utils::update_option('credentials', $existing, Schema::getConstant('GLOBAL_SETTINGS_KEY'));
209 $updatedSettings = Utils::update_option('settings', $settings, Schema::getConstant('GLOBAL_SETTINGS_KEY'));
210
211 if(!$updated) $serviceOk = false;
212 if(!$updatedSettings) $settingsOk = false;
213 }
214
215
216 if($action === 'all' || $action === 'service'){
217 // In 'config' source mode the credentials live in the WPMCS_CONFIG constant,
218 // so an empty config payload is expected and must not block the save.
219 if ( $service === false || ($configSource !== 'config' && empty($config)) || empty($bucketConfig)) return new WP_REST_Response( $result, 200 );
220
221 $updated = Utils::update_option(
222 'credentials',
223 [
224 'service' => $service,
225 'serviceLabel' => $serviceLabel,
226 'cdn' => $cdn,
227 'config' => $configSource === 'config' ? [] : $config,
228 'configSource' => $configSource,
229 'bucketConfig' => $bucketConfig,
230 'security' => $security
231 ],
232 Schema::getConstant('GLOBAL_SETTINGS_KEY')
233 );
234 if(!$updated) $serviceOk = false;
235
236 if($serviceOk) {
237 Utils::set_status('cdnRead', [
238 'status' => false,
239 'message' => '',
240 'lastChecked' => null
241 ]);
242 Utils::set_status('storageCredentials', [
243 'status' => false,
244 'message' => '',
245 'lastChecked' => null
246 ]);
247 }
248 }
249
250 if(($action === 'all' || $action === 'settings')) {
251 $updatedSettings = Utils::update_option('settings', $settings, Schema::getConstant('GLOBAL_SETTINGS_KEY'));
252 if(!$updatedSettings) $settingsOk = false;
253 }
254
255 // Clear plugin caches and refresh counts after any configuration save.
256 if(in_array($action, ['all', 'service', 'settings', 'cdn'], true)) {
257 if($action === 'all' || $action === 'service' || $action === 'settings') {
258 Integration::instance()->clear_all_meta(false);
259 }
260
261 if($action === 'all' || $action === 'settings') {
262 Utils::clear_all_content_meta(false, false);
263 }
264
265 Cache::flush_object_cache();
266 Counter::instance()->fetch_and_update();
267 }
268
269
270 if($serviceOk && $settingsOk) {
271 $result = [
272 'success' => true,
273 'message' => esc_html__('Configuration saved successfully', 'media-cloud-sync')
274 ];
275 }
276
277 return new WP_REST_Response( $result, 200 );
278 }
279
280
281 /**
282 * Refresh the Media Counts
283 *
284 */
285 public function refreshCounts( ) {
286 Cache::flush_object_cache();
287 Integration::instance()->clear_all_meta();
288 Counter::instance()->fetch_and_update();
289
290 $result = [
291 'success' => true,
292 'counts' => [
293 'all' => Counter::get_count(),
294 'categorized' => $this->getSortedMediaCounts()
295 ],
296 'message' => esc_html__('Media counts refreshed successfully', 'media-cloud-sync')
297 ];
298 return new WP_REST_Response( $result, 200 );
299 }
300
301
302 /**
303 * Start Upgrade
304 * @since 1.3.6
305 */
306 public function startUpgrade( $request ) {
307 $result = Upgrade::instance()->start_upgrade();
308 return new WP_REST_Response( $result, 200 );
309 }
310
311
312 /**
313 * Get Upgrade Status
314 * @since 1.3.6
315 */ public function getUpgradeStatus( $request ) {
316 $result = Upgrade::instance()->get_progress();
317 return new WP_REST_Response( $result, 200 );
318 }
319
320
321 /**
322 * Get Media Error Logs
323 * @since 1.2.13
324 */
325 public function getErrorLogs( $request ) {
326 $params = $request->get_params();
327 $type = isset($params['type']) ? $params['type'] : 'all';
328 $page = isset($params['page']) ? $params['page'] : null;
329 $per_page = isset($params['per_page']) ? $params['per_page'] : null;
330
331 if($type !== 'all') {
332 $logs = Logger::instance()->get_logs_by_type($type, $page, $per_page);
333 } else {
334 $logs = Logger::instance()->get_all_logs($page, $per_page);
335 }
336
337 $result = [
338 'success' => true,
339 'logs' => $logs,
340 'message' => esc_html__('Error logs fetched successfully', 'media-cloud-sync')
341 ];
342 return new WP_REST_Response( $result, 200 );
343 }
344
345
346 /**
347 * Clear all error logs for a sync type (e.g. stale entries from earlier failed attempts).
348 * @since 1.3.13
349 */
350 public function clearErrorLogs( $request ) {
351 $type = isset($request->get_params()['type']) ? $request->get_params()['type'] : '';
352
353 if (empty($type) || !Sync::instance()->get_class_by_action($type)) {
354 return new WP_REST_Response( [
355 'success' => false,
356 'message' => esc_html__('Invalid action', 'media-cloud-sync')
357 ], 200 );
358 }
359
360 Logger::instance()->remove_logs_by_type($type);
361
362 $result = [
363 'success' => true,
364 'message' => esc_html__('Error logs cleared', 'media-cloud-sync')
365 ];
366 return new WP_REST_Response( $result, 200 );
367 }
368
369
370 /**
371 * Get Status
372 * @since 1.2.13
373 */
374 public function getStatus( $request ) {
375 // Fetch and update media counts for make sure they are up to date
376 $action = isset($request->get_params()['action']) ? $request->get_params()['action'] : 'all';
377 $status = Sync::instance()->get_status();
378
379 if($action !== 'all') {
380 $status = isset($status[$action]) ? $status[$action] : [];
381 }
382
383 $result = [
384 'success' => true,
385 'status' => $status,
386 'counts' => [
387 'all' => Counter::get_count(),
388 'categorized' => $this->getSortedMediaCounts()
389 ],
390 'message' => esc_html__('Status fetched successfully', 'media-cloud-sync')
391 ];
392
393 return new WP_REST_Response( $result, 200 );
394 }
395
396
397 /**
398 * Start Sync
399 * @since 1.2.13
400 */
401 public function startSync( $data ) {
402 $action = isset($data->get_params()['action']) ? $data->get_params()['action'] : '';
403 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
404 $result = [
405 'success' => false,
406 'message' => esc_html__('Invalid action', 'media-cloud-sync')
407 ];
408 return new WP_REST_Response( $result, 200 );
409 }
410 if(!Utils::is_service_enabled()) {
411 $result = [
412 'success' => false,
413 'message' => Utils::get_service_configuration_error() ?: esc_html__('Storage is not configured correctly.', 'media-cloud-sync')
414 ];
415 return new WP_REST_Response( $result, 200 );
416 }
417 $status = Sync::instance()->start($action);
418
419 // Sync::start() passes a job's own precondition-failure array straight through
420 // (e.g. no destination configured) instead of masking it as a started status.
421 if (is_array($status) && isset($status['success']) && $status['success'] === false) {
422 return new WP_REST_Response( $status, 200 );
423 }
424
425 $result = [
426 'success' => true,
427 'status' => $status,
428 'message' => esc_html__('Sync started successfully', 'media-cloud-sync')
429 ];
430 return new WP_REST_Response( $result, 200 );
431 }
432
433
434 /**
435 * Pause Sync
436 * @since 1.2.13
437 */
438 public function pauseSync( $data ) {
439 $action = isset($data->get_params()['action']) ? $data->get_params()['action'] : '';
440 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
441 $result = [
442 'success' => false,
443 'message' => esc_html__('Invalid action', 'media-cloud-sync')
444 ];
445 return new WP_REST_Response( $result, 200 );
446 }
447 $status = Sync::instance()->pause($action);
448
449 $result = [
450 'success' => true,
451 'status' => $status,
452 'message' => esc_html__('Sync paused successfully', 'media-cloud-sync')
453 ];
454 return new WP_REST_Response( $result, 200 );
455 }
456
457
458 /**
459 * Save the sync method ('ajax'|'cron'|'mixed') preference for a sync type.
460 * @since 1.3.13
461 */
462 public function setSyncMethod( $data ) {
463 $params = $data->get_params();
464 $action = isset($params['action']) ? sanitize_text_field($params['action']) : '';
465 $method = isset($params['sync_method']) ? sanitize_text_field($params['sync_method']) : '';
466
467 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
468 return new WP_REST_Response( [
469 'success' => false,
470 'message' => esc_html__('Invalid action', 'media-cloud-sync')
471 ], 200 );
472 }
473
474 $saved = Sync::instance()->set_sync_method($action, $method);
475 if(!$saved) {
476 return new WP_REST_Response( [
477 'success' => false,
478 'message' => esc_html__('Invalid sync method', 'media-cloud-sync')
479 ], 200 );
480 }
481
482 $result = [
483 'success' => true,
484 'sync_method' => $method,
485 'status' => Sync::instance()->get_class_by_action($action)->get_status(),
486 ];
487 return new WP_REST_Response( $result, 200 );
488 }
489
490 /**
491 * Resume Sync
492 * @since 1.2.13
493 */
494 public function resumeSync( $data ) {
495 $action = isset($data->get_params()['action']) ? $data->get_params()['action'] : '';
496 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
497 $result = [
498 'success' => false,
499 'message' => esc_html__('Invalid action', 'media-cloud-sync')
500 ];
501 return new WP_REST_Response( $result, 200 );
502 }
503 $status = Sync::instance()->resume($action);
504
505 $result = [
506 'success' => true,
507 'status' => $status,
508 'message' => esc_html__('Sync resumed successfully', 'media-cloud-sync')
509 ];
510 return new WP_REST_Response( $result, 200 );
511 }
512
513
514 /**
515 * Stop Sync
516 * @since 1.2.13
517 */
518 public function stopSync( $data ) {
519 $action = isset($data->get_params()['action']) ? $data->get_params()['action'] : '';
520 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
521 $result = [
522 'success' => false,
523 'message' => esc_html__('Invalid action', 'media-cloud-sync')
524 ];
525 return new WP_REST_Response( $result, 200 );
526 }
527 $status = Sync::instance()->stop($action);
528
529 $result = [
530 'success' => true,
531 'status' => $status,
532 'counts' => [
533 'all' => Counter::get_count(),
534 'categorized' => $this->getSortedMediaCounts()
535 ],
536 'message' => esc_html__('Sync stopped successfully', 'media-cloud-sync')
537 ];
538 return new WP_REST_Response( $result, 200 );
539 }
540
541
542 /**
543 * Tick Sync — process a small batch synchronously, driving Ajax/Mixed sync mode.
544 * @since 1.3.13
545 */
546 public function tickSync( $data ) {
547 $params = $data->get_params();
548 $action = isset($params['action']) ? $params['action'] : '';
549
550 if ( ! Sync::instance()->get_class_by_action( $action ) ) {
551 $result = [
552 'success' => false,
553 'message' => esc_html__('Invalid action', 'media-cloud-sync')
554 ];
555 return new WP_REST_Response( $result, 200 );
556 }
557
558 // Defense in depth — the frontend should never call this in free/unlicensed mode, but
559 // the endpoint must not trust that, and must not silently no-op: an unlicensed call
560 // needs a clear rejection so the frontend's tick loop stops instead of retrying forever.
561 if ( ! Utils::is_pro_licensed() ) {
562 $result = [
563 'success' => false,
564 'message' => esc_html__('Ajax sync requires an active Pro license', 'media-cloud-sync')
565 ];
566 return new WP_REST_Response( $result, 200 );
567 }
568
569 // Clamp regardless of what the frontend sends — the endpoint itself must enforce the
570 // ceiling, since a batch of slow uploads processed sequentially in one request risks
571 // exceeding reverse-proxy/webserver timeouts that process_iterations() can't see.
572 $batch = isset($params['batch']) ? (int) $params['batch'] : 5;
573 $batch = min(10, max(1, $batch));
574
575 $status = Sync::instance()->tick($action, $batch);
576
577 $result = [
578 'success' => true,
579 'status' => $status,
580 'message' => esc_html__('Sync ticked successfully', 'media-cloud-sync')
581 ];
582
583 // Deliberately omitted on every tick (this endpoint may be hit ~once/second while a
584 // sync runs, and Counter::get_count() is a real query) — but the Dashboard's own
585 // Statistics widget reads a *different* redux slice (common.counts) than the Sync
586 // screen's progress (sync[action]), only refreshed via the slower ~2-3s useSyncPolling
587 // cadence. That's an acceptable few-seconds lag while a sync is actively running, but
588 // right when it finishes it becomes a visibly wrong, stuck-looking number on the
589 // Dashboard until the next poll happens to catch up. Only pay for the query at that
590 // one transition, not on every tick.
591 if ( isset( $status['status'] ) && $status['status'] !== 'running' ) {
592 $result['counts'] = [
593 'all' => Counter::get_count(),
594 'categorized' => $this->getSortedMediaCounts()
595 ];
596 }
597 return new WP_REST_Response( $result, 200 );
598 }
599
600
601 /**
602 * Retry a Media Sync Error
603 */
604 public function retrySingle( $data ) {
605 $params = $data->get_params();
606 $id = isset($params['id']) ? $params['id'] : '';
607 $source_type = isset($params['source_type']) ? $params['source_type'] : 'media_library';
608 $type = isset($params['type']) ? $params['type'] : '';
609 $status = false;
610 if(empty($id) || empty($source_type) || empty($type)) {
611 $result = [
612 'success' => false,
613 'message' => esc_html__('Invalid parameters', 'media-cloud-sync')
614 ];
615 return new WP_REST_Response( $result, 200 );
616 }
617 // Retry Sync
618 $handler = Sync::instance()->get_class_by_action($type);
619 if(!$handler) {
620 $result = [
621 'success' => false,
622 'message' => esc_html__('Invalid action', 'media-cloud-sync')
623 ];
624 return new WP_REST_Response( $result, 200 );
625 }
626 if(!method_exists($handler, 'retry_single')) {
627 $result = [
628 'success' => false,
629 'message' => esc_html__('Retry is not available for this sync type.', 'media-cloud-sync')
630 ];
631 return new WP_REST_Response( $result, 200 );
632 }
633 $handler->retry_single($id, $source_type);
634
635 $status = Utils::is_empty(Logger::instance()->get_log($type, $id, $source_type)) ? true : false;
636
637 $result = [
638 'success' => $status,
639 'message' => $status ? esc_html__('Media synced successfully', 'media-cloud-sync') : esc_html__('Media sync failed', 'media-cloud-sync')
640 ];
641 return new WP_REST_Response( $result, 200 );
642 }
643
644
645 /**
646 * Get Sorted Media Counts
647 * Sorts media counts by source type
648 * @since 1.2.13
649 */
650 private function getSortedMediaCounts() {
651 $sorted_counts = [];
652 $detailed_counts = Counter::get_count( 'all', false );
653 if(!empty($detailed_counts)) {
654 $source_labels = Integration::$source_labels;
655 if(!empty($source_labels)) {
656 $prefixes = array_keys($source_labels);
657 foreach($detailed_counts as $source_type => $counts) {
658 $found_prefix = false;
659 foreach($prefixes as $prefix) {
660 $found_prefix = strpos($source_type, $prefix) === 0 ? $prefix : false;
661 if($found_prefix !== false) break;
662 }
663
664 if($found_prefix !== false) {
665 $sorted_counts[$found_prefix] = [
666 'label' => $source_labels[$found_prefix],
667 'uploaded' => isset( $sorted_counts[ $found_prefix ]['uploaded'] )
668 ? $sorted_counts[ $found_prefix ]['uploaded'] + $counts['uploaded']
669 : $counts['uploaded'],
670 'total' => isset( $sorted_counts[ $found_prefix ]['total'] )
671 ? $sorted_counts[ $found_prefix ]['total'] + $counts['total']
672 : $counts['total']
673 ];
674 }
675 }
676 }
677 }
678
679 return $sorted_counts;
680 }
681
682
683 /**
684 * Helper function to create Adding Route
685 * @since 1.0.0
686 */
687 private function add_route( $slug, $callBack, $method = 'GET' ) {
688 register_rest_route(
689 $this->token . '/v1',
690 $slug,
691 array(
692 'methods' => $method,
693 'callback' => array( $this, $callBack ),
694 'permission_callback' => array( $this, 'getPermission' ),
695 ) );
696 }
697
698 /**
699 * Permission Callback
700 **/
701 public function getPermission() {
702 if ( current_user_can( 'manage_options' ) ) {
703 return true;
704 } else {
705 return false;
706 }
707 }
708
709 /**
710 * Ensures only one instance of Class is loaded or can be loaded.
711 *
712 * @return Api Class instance
713 * @since 1.0.0
714 * @static
715 */
716 public static function instance(){
717 if (is_null(self::$instance)) {
718 self::$instance = new self();
719 }
720 return self::$instance;
721 }
722 }
723