chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow - Standardized file signatures to Descomplicar® format - Updated development configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
339
src/includes/class-api-init.php
Normal file
339
src/includes/class-api-init.php
Normal file
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* KiviCare API Initialization
|
||||
*
|
||||
* @package KiviCare_API
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main API initialization class.
|
||||
*
|
||||
* @class KiviCare_API_Init
|
||||
*/
|
||||
class KiviCare_API_Init {
|
||||
|
||||
/**
|
||||
* The single instance of the class.
|
||||
*
|
||||
* @var KiviCare_API_Init
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static $_instance = null;
|
||||
|
||||
/**
|
||||
* REST API namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const API_NAMESPACE = 'kivicare/v1';
|
||||
|
||||
/**
|
||||
* Main KiviCare_API_Init Instance.
|
||||
*
|
||||
* Ensures only one instance of KiviCare_API_Init is loaded or can be loaded.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @static
|
||||
* @return KiviCare_API_Init - Main instance.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( is_null( self::$_instance ) ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* KiviCare_API_Init Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->init_hooks();
|
||||
$this->includes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into actions and filters.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private function init_hooks() {
|
||||
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
|
||||
add_action( 'init', array( $this, 'check_dependencies' ) );
|
||||
add_filter( 'rest_pre_serve_request', array( $this, 'rest_pre_serve_request' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include required core files.
|
||||
*/
|
||||
public function includes() {
|
||||
// Base classes will be included here as they are created
|
||||
// include_once KIVICARE_API_ABSPATH . 'services/class-jwt-auth.php';
|
||||
// include_once KIVICARE_API_ABSPATH . 'endpoints/class-auth-endpoints.php';
|
||||
// etc.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check plugin dependencies.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function check_dependencies() {
|
||||
// Check if KiviCare plugin is active
|
||||
if ( ! $this->is_kivicare_active() ) {
|
||||
add_action( 'admin_notices', array( $this, 'kivicare_dependency_notice' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check required database tables
|
||||
if ( ! $this->check_kivicare_tables() ) {
|
||||
add_action( 'admin_notices', array( $this, 'database_tables_notice' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if KiviCare plugin is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_kivicare_active() {
|
||||
return is_plugin_active( 'kivicare-clinic-&-patient-management-system/kivicare-clinic-&-patient-management-system.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if required KiviCare database tables exist.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function check_kivicare_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$required_tables = array(
|
||||
'kc_clinics',
|
||||
'kc_appointments',
|
||||
'kc_patient_encounters',
|
||||
'kc_prescription',
|
||||
'kc_bills',
|
||||
'kc_services',
|
||||
'kc_doctor_clinic_mappings',
|
||||
'kc_patient_clinic_mappings',
|
||||
);
|
||||
|
||||
foreach ( $required_tables as $table ) {
|
||||
$table_name = $wpdb->prefix . $table;
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$table_exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) );
|
||||
|
||||
if ( $table_name !== $table_exists ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display admin notice for KiviCare dependency.
|
||||
*/
|
||||
public function kivicare_dependency_notice() {
|
||||
?>
|
||||
<div class="notice notice-error">
|
||||
<p>
|
||||
<strong><?php esc_html_e( 'KiviCare API Error:', 'kivicare-api' ); ?></strong>
|
||||
<?php esc_html_e( 'KiviCare Plugin is required for KiviCare API to work properly.', 'kivicare-api' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display admin notice for missing database tables.
|
||||
*/
|
||||
public function database_tables_notice() {
|
||||
?>
|
||||
<div class="notice notice-error">
|
||||
<p>
|
||||
<strong><?php esc_html_e( 'KiviCare API Error:', 'kivicare-api' ); ?></strong>
|
||||
<?php esc_html_e( 'Required KiviCare database tables are missing. Please ensure KiviCare plugin is properly activated.', 'kivicare-api' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST API routes.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function register_rest_routes() {
|
||||
// Only register routes if dependencies are met
|
||||
if ( ! $this->check_dependencies() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow plugins to hook into REST API registration.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
do_action( 'kivicare_api_register_rest_routes' );
|
||||
|
||||
// Register a test endpoint to verify API is working
|
||||
register_rest_route(
|
||||
self::API_NAMESPACE,
|
||||
'/status',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_api_status' ),
|
||||
'permission_callback' => array( $this, 'check_api_permissions' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get API status endpoint.
|
||||
*
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public function get_api_status( $request ) {
|
||||
global $wpdb;
|
||||
|
||||
// Get basic KiviCare database stats
|
||||
$clinic_count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}kc_clinics WHERE status = 1" );
|
||||
$patient_count = $wpdb->get_var(
|
||||
"SELECT COUNT(DISTINCT u.ID) FROM {$wpdb->users} u
|
||||
INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id
|
||||
WHERE um.meta_key = '{$wpdb->prefix}capabilities'
|
||||
AND um.meta_value LIKE '%patient%'"
|
||||
);
|
||||
|
||||
$response_data = array(
|
||||
'status' => 'active',
|
||||
'version' => KIVICARE_API_VERSION,
|
||||
'namespace' => self::API_NAMESPACE,
|
||||
'timestamp' => current_time( 'mysql' ),
|
||||
'wordpress_version' => get_bloginfo( 'version' ),
|
||||
'php_version' => phpversion(),
|
||||
'kivicare_active' => $this->is_kivicare_active(),
|
||||
'statistics' => array(
|
||||
'active_clinics' => (int) $clinic_count,
|
||||
'total_patients' => (int) $patient_count,
|
||||
),
|
||||
'endpoints' => $this->get_available_endpoints(),
|
||||
);
|
||||
|
||||
return rest_ensure_response( $response_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of available API endpoints.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_available_endpoints() {
|
||||
return array(
|
||||
'authentication' => array(
|
||||
'POST /auth/login',
|
||||
'POST /auth/refresh',
|
||||
'POST /auth/logout',
|
||||
),
|
||||
'clinics' => array(
|
||||
'GET /clinics',
|
||||
'POST /clinics',
|
||||
'GET /clinics/{id}',
|
||||
'PUT /clinics/{id}',
|
||||
'DELETE /clinics/{id}',
|
||||
),
|
||||
'patients' => array(
|
||||
'GET /patients',
|
||||
'POST /patients',
|
||||
'GET /patients/{id}',
|
||||
'PUT /patients/{id}',
|
||||
'GET /patients/{id}/encounters',
|
||||
),
|
||||
'appointments' => array(
|
||||
'GET /appointments',
|
||||
'POST /appointments',
|
||||
'GET /appointments/{id}',
|
||||
'PUT /appointments/{id}',
|
||||
'DELETE /appointments/{id}',
|
||||
),
|
||||
'encounters' => array(
|
||||
'GET /encounters',
|
||||
'POST /encounters',
|
||||
'GET /encounters/{id}',
|
||||
'PUT /encounters/{id}',
|
||||
'POST /encounters/{id}/prescriptions',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check API permissions.
|
||||
*
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function check_api_permissions( $request ) {
|
||||
// For status endpoint, allow if user can manage options or has API access
|
||||
if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_kivicare_api' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Allow unauthenticated access to status endpoint for basic health checks
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify REST API response headers.
|
||||
*
|
||||
* @param bool $served Whether the request has already been served.
|
||||
* @param WP_HTTP_Response $result Result to send to the client.
|
||||
* @param WP_REST_Request $request Request used to generate the response.
|
||||
* @param WP_REST_Server $server Server instance.
|
||||
* @return bool
|
||||
*/
|
||||
public function rest_pre_serve_request( $served, $result, $request, $server ) {
|
||||
// Only modify responses for our API namespace
|
||||
$route = $request->get_route();
|
||||
if ( strpos( $route, '/' . self::API_NAMESPACE . '/' ) !== 0 ) {
|
||||
return $served;
|
||||
}
|
||||
|
||||
// Add custom headers
|
||||
$result->header( 'X-KiviCare-API-Version', KIVICARE_API_VERSION );
|
||||
$result->header( 'X-Powered-By', 'KiviCare API by Descomplicar®' );
|
||||
|
||||
// Add CORS headers for development
|
||||
if ( defined( 'KIVICARE_API_DEBUG' ) && KIVICARE_API_DEBUG ) {
|
||||
$result->header( 'Access-Control-Allow-Origin', '*' );
|
||||
$result->header( 'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS' );
|
||||
$result->header( 'Access-Control-Allow-Headers', 'Authorization, Content-Type, X-WP-Nonce' );
|
||||
}
|
||||
|
||||
return $served;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_namespace() {
|
||||
return self::API_NAMESPACE;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user