Skip to content
wiki.fftac.org

Integrating Participants Database Into Anti Christ - Source Excerpt 03 - Step-by-step implementation plan

Back to Integrating Participants Database Into Anti Christ

Summary

This source excerpt begins near Step-by-step implementation plan and preserves the surrounding evidence from Anti-Christ.org/agent-file-handoff/Archive/2026-05-10-improvement-and-content/Improvement/Integrating Participants Database into anti-christ.org.md.

**Source path:** Anti-Christ.org/agent-file-handoff/Archive/2026-05-10-improvement-and-content/Improvement/Integrating Participants Database into anti-christ.org.md

Keep the site’s existing theme-managed registration form as the user-facing entry point. When the user is created, immediately create or link a Participants Database record keyed by `wp_user_id`. If you choose the official PDb WordPress User Profile add-on, it can also create WP users from PDb signup/approval flows, but for this site I would still preserve the current theme-centered member-registration UX because the public portal is already designed around it. The add-on documentation also notes that **WordPress**, not Participants Database, handles new-account passwords. citeturn15view0turn10view0

#### Login

Keep standard WordPress login/session behavior. This is compatible with protected pages, existing redirects, and any future sitewide member-only functionality. Do **not** replace this with PDb’s private-link model or the Participant Login add-on for the core member workflow. citeturn15view0turn10view1turn10view2

#### Password reset

Continue to use WordPress password-reset flows. WordPress core provides `retrieve_password()` for reset-email handling, and the site already publicly exposes a reset-link flow from the Membership page. Participants Database should not hold member passwords for this architecture. citeturn15view0turn25view8turn10view0

#### Profile editing

If you use the official add-on, create a front-end profile page with `[pdb_user_profile]` and point the member dashboard/account menu there. The add-on docs state that the shortcode provides a frontend profile page and that the plugin will redirect the user’s profile link to that frontend page instead of the backend profile page. If you stay purely custom, expose a custom `/account/profile/` page that edits WP identity fields plus PDb extended fields in a single form. citeturn10view0

### Step-by-step implementation plan

#### Prepare staging and backups

1. Clone the site to staging.
2. Export the database before any plugin install or field changes.
3. Back up `wp-content/uploads`.
4. Inventory the current theme’s membership routes, redirects, and role names. The public site confirms those flows exist, but the internal implementation still needs inspection in staging. citeturn15view0

Recommended commands:

' ' ' bash
wp db export pre-pdb-integration.sql
wp plugin install participants-database --activate
wp user list --fields=ID,user_login,user_email,roles --format=table
' ' ' 

#### Define Participants Database field groups

Create at least these field groups in **Manage Database Fields**:

- **Public Profile**
- **Private Profile**
- **Program Intake**
- **Administrative**
- **Compliance**

Use **view mode** carefully:

- `public` for intentionally public member metadata
- `private` for self-manageable member-only fields
- `admin` for moderation/status/staff notes/compliance internals citeturn32view1turn32view7

#### Create the linkage and mapped fields

At minimum create:

- `wp_user_id` — hidden, read-only, admin/private group
- `wp_user_login` — hidden or text-line, read-only
- `email`
- `first_name`
- `last_name`
- `public_alias`
- `primary_interest`
- `intake_lane`
- `member_status`
- `consent_privacy`
- `consent_terms`
- `consent_version`
- `consent_timestamp`
- `consent_ip`

Keep `wp_user_id` out of public-facing forms except where it is dynamically populated for an authenticated user. The plugin supports dynamic hidden values, and official examples show capturing values like `current_user->user_login` through hidden fields. citeturn11view4turn23view0

#### Configure validation and anti-spam

Use server-side validation for all important fields, and add HTML5/client-side validation for UX. Participants Database supports **required**, **email**, **CAPTCHA**, and **regex/match** validation, while its documentation recommends a hybrid client-side/server-side approach when needed. For email confirmation, use a second “verify email” field with **Regex/Match** pointing to the main email field. citeturn32view0turn23view1turn23view0

Use anti-spam in layers:

- keep the site’s existing honeypot-like hidden inputs if they are already part of the theme forms
- use PDb’s built-in CAPTCHA or the official reCAPTCHA add-on where PDb forms are public
- use an approval/moderation step for open intake flows where spam risk matters, because the docs explicitly note that simple CAPTCHA does not stop human-submitted spam. citeturn15view0turn23view0turn33search5

#### Choose one of two integration tracks

### Track using the official WordPress User Profile add-on

This is the fastest route if premium add-ons are acceptable.

1. Install the add-on.
2. In its settings, map:
   - First Name Field
   - Last Name Field
   - Email Field
   - User Login Field
   - optional User Avatar Field
3. Enable **Create PDb Record for WP User**.
4. Create a frontend profile page with:

' ' ' text
[pdb_user_profile template=frontend-profile-flexbox]
' ' ' 

5. Add that profile page into the member dashboard/account navigation.
6. Keep registration/login/reset in the current theme unless you have a strategic reason to move them. citeturn10view0

### Track using custom code

If you do not want the premium add-on, add a small bridge plugin or mu-plugin.

#### Create or update the linked PDb record when a WP user is created or updated

' ' ' php
<?php
/**
 * Plugin Name: FFTAC Participants Database Bridge
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

function fftac_pdb_table() {
	global $wpdb;
	return $wpdb->prefix . 'participants_database';
}

function fftac_find_pdb_record_id_by_user( int $user_id ): ?int {
	global $wpdb;
	$table = fftac_pdb_table();

	// Requires a Participants Database field named "wp_user_id".
	$id = $wpdb->get_var(
		$wpdb->prepare(
			"SELECT id FROM {$table} WHERE wp_user_id = %d LIMIT 1",
			$user_id
		)
	);

	return $id ? (int) $id : null;
}

function fftac_sync_wp_user_to_pdb( int $user_id ): void {
	if ( ! class_exists( 'Participants_Db' ) ) {
		return;
	}

	$user = get_userdata( $user_id );
	if ( ! $user instanceof WP_User ) {
		return;
	}

	$data = array(
		'wp_user_id'    => $user->ID,
		'wp_user_login' => $user->user_login,
		'email'         => $user->user_email,
		'first_name'    => get_user_meta( $user->ID, 'first_name', true ),
		'last_name'     => get_user_meta( $user->ID, 'last_name', true ),
	);

	$record_id = fftac_find_pdb_record_id_by_user( $user_id );

	if ( $record_id ) {
		Participants_Db::write_participant( $data, $record_id );
	} else {
		Participants_Db::write_participant( $data );
	}
}

add_action( 'user_register', 'fftac_sync_wp_user_to_pdb', 20 );
add_action( 'profile_update', 'fftac_sync_wp_user_to_pdb', 20 );
' ' ' 

This uses standard WordPress user hooks plus the documented PDb `Participants_Db::write_participant()` method. WordPress documents `user_register` as the action that fires immediately after a new user is registered, and PDb documents `write_participant()` for record creation or update. citeturn26search5turn16view0

#### Sync certain profile values back to WordPress after a front-end PDb update

' ' ' php
<?php
add_action( 'pdb-before_update_thanks', function( $submission ) {
	if ( ! is_user_logged_in() ) {
		return;
	}

	$values = isset( $submission->participant_values ) && is_array( $submission->participant_values )
		? $submission->participant_values
		: array();

	if ( empty( $values ) ) {
		return;
	}

	$user_id  = get_current_user_id();
	$userdata = array( 'ID' => $user_id );

	if ( isset( $values['email'] ) && is_email( $values['email'] ) ) {
		$userdata['user_email'] = $values['email'];
	}
	if ( isset( $values['first_name'] ) ) {
		update_user_meta( $user_id, 'first_name', sanitize_text_field( $values['first_name'] ) );
	}
	if ( isset( $values['last_name'] ) ) {
		update_user_meta( $user_id, 'last_name', sanitize_text_field( $values['last_name'] ) );
	}

	if ( count( $userdata ) > 1 ) {
		wp_update_user( $userdata );
	}
}, 10, 1 );
' ' ' 

The `pdb-before_update_thanks` action runs after a frontend record update; WordPress provides `wp_update_user()` for user updates. citeturn16view0turn26search9

#### Remap backend access to custom capabilities

' ' ' php
<?php
add_filter( 'pdb-access_capability', function( $capability, $context ) {
	switch ( $context ) {
		case 'list participants':
		case 'edit participant':
		case 'add participant':
			return 'fftac_manage_participants';

		case 'plugin settings':
		case 'manage fields':
		case 'upload csv':
		case 'delete participants':
		case 'export csv':
			return 'fftac_admin_participants';

		default:
			return $capability;
	}
}, 10, 2 );

add_action( 'init', function() {
	add_role(
		'fftac_participant_manager',
		'FFTAC Participant Manager',
		array(
			'read'                     => true,
			'fftac_manage_participants'=> true,
		)
	);

	add_role(
		'fftac_participant_admin',
		'FFTAC Participant Admin',
		array(
			'read'                     => true,
			'fftac_manage_participants'=> true,
			'fftac_admin_participants' => true,
		)
	);
} );
' ' '