# 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/)