# WordPress Integration Guide for Incident Management System ## Easiest Integration Options ### Option 1: WordPress Plugin - Custom REST API (Recommended) This plugin creates a bridge between your existing Node.js application and WordPress. 1. **Install and activate these plugins**: - [Custom Post Type UI](https://wordpress.org/plugins/custom-post-type-ui/) - [Advanced Custom Fields](https://wordpress.org/plugins/advanced-custom-fields/) - [ACF to REST API](https://wordpress.org/plugins/acf-to-rest-api/) 2. **Create a custom plugin** by copying this code to a file named `incident-management-api.php` in your `/wp-content/plugins/` directory: ```php 'Incidents', 'singular_name' => 'Incident', ); $args = array( 'labels' => $labels, 'public' => true, 'has_archive' => true, 'show_in_rest' => true, 'menu_icon' => 'dashicons-clipboard', 'supports' => array('title', 'custom-fields'), ); register_post_type('incident', $args); } add_action('init', 'register_incident_cpt'); // Create shortcode to embed the incident app function incident_app_shortcode($atts) { $attributes = shortcode_atts(array( 'view' => 'dashboard', // default view ), $atts); $view = $attributes['view']; return '
'; } add_shortcode('incident_app', 'incident_app_shortcode'); // Register REST API endpoints function register_incident_api_routes() { register_rest_route('incident-api/v1', '/incidents', array( 'methods' => 'GET', 'callback' => 'get_incidents', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); register_rest_route('incident-api/v1', '/incidents/(?P\d+)', array( 'methods' => 'GET', 'callback' => 'get_incident', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); register_rest_route('incident-api/v1', '/incidents', array( 'methods' => 'POST', 'callback' => 'create_incident', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); register_rest_route('incident-api/v1', '/incidents/(?P\d+)', array( 'methods' => 'PUT', 'callback' => 'update_incident', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); register_rest_route('incident-api/v1', '/incidents/(?P\d+)', array( 'methods' => 'DELETE', 'callback' => 'delete_incident', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); register_rest_route('incident-api/v1', '/stats', array( 'methods' => 'GET', 'callback' => 'get_incident_stats', 'permission_callback' => function() { return current_user_can('edit_posts'); } )); } add_action('rest_api_init', 'register_incident_api_routes'); // API Endpoint implementations function get_incidents($request) { $args = array( 'post_type' => 'incident', 'posts_per_page' => -1, ); $posts = get_posts($args); $incidents = array(); foreach ($posts as $post) { $incident = array( 'id' => $post->ID, 'incidentNumber' => get_field('incident_number', $post->ID), 'date' => get_field('date', $post->ID), 'time' => get_field('time', $post->ID), 'location' => get_field('location', $post->ID), 'incidentType' => get_field('incident_type', $post->ID), // Add all other incident fields here ); $incidents[] = $incident; } return array('data' => $incidents, 'total' => count($incidents)); } function get_incident($request) { $id = $request['id']; $post = get_post($id); if (!$post || $post->post_type !== 'incident') { return new WP_Error('not_found', 'Incident not found', array('status' => 404)); } $incident = array( 'id' => $post->ID, 'incidentNumber' => get_field('incident_number', $post->ID), 'date' => get_field('date', $post->ID), 'time' => get_field('time', $post->ID), 'location' => get_field('location', $post->ID), 'incidentType' => get_field('incident_type', $post->ID), // Add all other incident fields here ); return $incident; } function create_incident($request) { $params = $request->get_params(); $post_data = array( 'post_title' => 'Incident ' . $params['incidentNumber'], 'post_type' => 'incident', 'post_status' => 'publish', ); $post_id = wp_insert_post($post_data); if (is_wp_error($post_id)) { return $post_id; } // Save all incident fields update_field('incident_number', $params['incidentNumber'], $post_id); update_field('date', $params['date'], $post_id); update_field('time', $params['time'], $post_id); update_field('location', $params['location'], $post_id); update_field('incident_type', $params['incidentType'], $post_id); // Add all other incident fields here return get_incident(array('id' => $post_id)); } function update_incident($request) { $id = $request['id']; $params = $request->get_params(); $post = get_post($id); if (!$post || $post->post_type !== 'incident') { return new WP_Error('not_found', 'Incident not found', array('status' => 404)); } // Update post title if incident number changed if (isset($params['incidentNumber'])) { wp_update_post(array( 'ID' => $id, 'post_title' => 'Incident ' . $params['incidentNumber'], )); update_field('incident_number', $params['incidentNumber'], $id); } // Update all provided fields if (isset($params['date'])) update_field('date', $params['date'], $id); if (isset($params['time'])) update_field('time', $params['time'], $id); if (isset($params['location'])) update_field('location', $params['location'], $id); if (isset($params['incidentType'])) update_field('incident_type', $params['incidentType'], $id); // Add all other incident fields here return get_incident(array('id' => $id)); } function delete_incident($request) { $id = $request['id']; $post = get_post($id); if (!$post || $post->post_type !== 'incident') { return new WP_Error('not_found', 'Incident not found', array('status' => 404)); } $result = wp_delete_post($id, true); if (!$result) { return new WP_Error('delete_failed', 'Failed to delete incident', array('status' => 500)); } return array('success' => true); } function get_incident_stats($request) { $args = array( 'post_type' => 'incident', 'posts_per_page' => -1, ); $posts = get_posts($args); $total = count($posts); $by_type = array(); foreach ($posts as $post) { $type = get_field('incident_type', $post->ID); if (!isset($by_type[$type])) { $by_type[$type] = 0; } $by_type[$type]++; } // Get recent incidents $recent_args = array( 'post_type' => 'incident', 'posts_per_page' => 20, 'orderby' => 'meta_value', 'meta_key' => 'date', 'order' => 'DESC', ); $recent_posts = get_posts($recent_args); $recent_incidents = array(); foreach ($recent_posts as $post) { $incident = array( 'id' => $post->ID, 'incidentNumber' => get_field('incident_number', $post->ID), 'date' => get_field('date', $post->ID), 'time' => get_field('time', $post->ID), 'location' => get_field('location', $post->ID), 'incidentType' => get_field('incident_type', $post->ID), // Add other fields needed for recent incidents display ); $recent_incidents[] = $incident; } return array( 'totalIncidents' => $total, 'byType' => $by_type, 'recentIncidents' => $recent_incidents, ); } ``` 3. **Create ACF Fields**: - Go to Custom Fields → Add New - Create a field group called "Incident Fields" - Add all the fields from your incident schema (incident_number, date, time, location, etc.) - Set Location Rules to Post Type = Incident 4. **Update your React frontend**: - Modify API endpoints to use WordPress REST API format - Example: ```javascript // Before fetch('/api/incidents') // After fetch('/wp-json/incident-api/v1/incidents') ``` ### Option 2: Use an Existing WordPress Incident Management Plugin These existing plugins offer similar functionality: 1. **Incident IQ**: [https://wordpress.org/plugins/incident-iq/](https://wordpress.org/plugins/incident-iq/) - Helps track incidents and responses 2. **Crisis Management System**: [https://wordpress.org/plugins/crisis-management-system/](https://wordpress.org/plugins/crisis-management-system/) - For emergency management scenarios 3. **Issue Tracker**: [https://wordpress.org/plugins/issue-tracker/](https://wordpress.org/plugins/issue-tracker/) - Can be adapted for incident management ### Option 3: Full JavaScript Integration (No PHP Required) 1. **Install and activate these plugins**: - [WP REST API Controller](https://wordpress.org/plugins/wp-rest-api-controller/) - [WP Webhooks](https://wordpress.org/plugins/wp-webhooks/) 2. **Create a WordPress page** to host your app. Add this to the page content: ```html
``` 3. **Host your Node.js app separately**: - Deploy your existing Node.js app to a hosting provider (Heroku, Vercel, etc.) - Configure CORS to accept requests from your WordPress domain - Point your React app to this backend ## Deployment Considerations 1. **Database**: - WordPress method: Uses WordPress database with custom post types - Separate method: Keeps your PostgreSQL database separate 2. **User Authentication**: - WordPress method: Uses WordPress user system - Separate method: Requires custom authentication integration 3. **Updates & Maintenance**: - WordPress method: Update through WordPress plugin mechanism - Separate method: Update backend and frontend independently ## Implementation Steps 1. **Choose an integration approach** based on your technical comfort level 2. **Set up data structure** in WordPress or your separate database 3. **Configure API endpoints** according to your chosen method 4. **Update frontend code** to connect to the right API endpoints 5. **Test thoroughly** before going live ## Additional Resources - [WordPress REST API Handbook](https://developer.wordpress.org/rest-api/) - [ACF Developer Documentation](https://www.advancedcustomfields.com/resources/) - [WP REST API Controller Docs](https://www.yikesinc.com/wp-rest-api-controller/)