Skip to content

frs-wp-users

Version: 2.2.0 Repository: derintolu/frs-wp-users

Advanced user profile management system with guest profiles, REST API, FluentCRM sync, Follow Up Boss integration, and intranet module.

Features

Implemented

IDFeaturePriority
FRS-USERS-001Profile ManagementP0
FRS-USERS-002FluentCRM IntegrationP1
FRS-USERS-003Profile Sync (Hub ↔ Marketing)P1
FRS-USERS-008Follow Up Boss IntegrationP1

Planned

IDFeaturePriority
FRS-USERS-004WordPress Abilities APIP1
FRS-USERS-005Intranet DirectoryP1
FRS-USERS-006Intranet ProfileP1
FRS-USERS-007Network-Wide BookmarksP2

Installation

bash
# Clone to plugins directory
git clone https://github.com/derintolu/frs-wp-users.git

# Activate
wp plugin activate frs-wp-users

Profile Roles

WordPress Roles (Capabilities)

RoleSlugURL Prefix
Loan Officerloan_officer/lo/
Real Estate Agentre_agent/agent/
Escrow Officerescrow_officer/escrow/
Property Managerproperty_manager/pm/
Dual Licensedual_license/lo/
Staffstaff/staff/
Leadershipleadership/leader/
Assistantassistant/staff/
Partnerpartner(none)

Company Roles (Directory Categorization)

Stored as multi-value frs_company_role meta:

Company RoleMaps to WP Role
loan_originatorloan_officer
broker_associatere_agent
sales_associatere_agent
escrow_officerescrow_officer
property_managerproperty_manager
partnerpartner
leadershipleadership
staffstaff

REST API

Base: /wp-json/frs-users/v1/

Endpoints

MethodEndpointAuthDescription
GET/profilesPublicList all profiles
POST/profilesEditorCreate profile
GET/profiles/{id}PublicGet single profile
PUT/profiles/{id}EditorUpdate profile
DELETE/profiles/{id}EditorDelete profile
GET/profiles/slug/{slug}PublicGet by profile slug
GET/profiles/user/{id|me}PublicGet by WordPress user ID
GET/service-areasPublicList all service areas
GET/vcard/{id}PublicDownload vCard
POST/meeting-requestPublicSubmit meeting request
POST/webhook/profile-updatedHMACProfile sync webhook

Example Request

bash
# Get loan originators in a specific region
curl -X GET \
  'https://myhub21.com/wp-json/frs-users/v1/profiles?company_role=loan_originator&region=los-angeles'

Example Response

json
{
  "data": [
    {
      "id": 45,
      "display_name": "Sarah Johnson",
      "first_name": "Sarah",
      "last_name": "Johnson",
      "email": "sarah@21stcenturylending.com",
      "frs_company_role": ["loan_originator"],
      "frs_job_title": "Senior Loan Officer",
      "frs_nmls": "1234567",
      "frs_phone_number": "(555) 123-4567",
      "frs_mobile_number": "(555) 987-6543",
      "frs_office": "Los Angeles",
      "frs_city_state": "Los Angeles, CA",
      "frs_region": "los-angeles",
      "frs_service_areas": ["Los Angeles", "Orange County", "Ventura"],
      "frs_biography": "15+ years helping families achieve homeownership...",
      "frs_headshot_id": 1234,
      "frs_profile_slug": "sarah-johnson",
      "frs_linkedin_url": "https://linkedin.com/in/sarahjohnson",
      "avatar_url": "https://myhub21.com/wp-content/uploads/avatars/sarah.jpg"
    }
  ],
  "total": 1,
  "pages": 1
}

Profile Meta Fields

All fields prefixed with frs_ and stored in wp_usermeta.

Core Fields

FieldMeta KeyType
Phonefrs_phone_numberstring
Mobilefrs_mobile_numberstring
Job Titlefrs_job_titlestring
Biographyfrs_biographytext
Headshotfrs_headshot_idattachment_id

Licensing Fields

FieldMeta KeyType
NMLSfrs_nmlsstring
NMLS Numberfrs_nmls_numberstring
License Numberfrs_license_numberstring
DRE Licensefrs_dre_licensestring

Location Fields

FieldMeta KeyType
Officefrs_officestring
City/Statefrs_city_statestring
Regionfrs_regionstring
Service Areasfrs_service_areasJSON array

Social Fields

FieldMeta Key
Facebookfrs_facebook_url
Instagramfrs_instagram_url
LinkedInfrs_linkedin_url
Twitterfrs_twitter_url
YouTubefrs_youtube_url
TikTokfrs_tiktok_url

Profile Fields

FieldMeta KeyType
Profile Slugfrs_profile_slugstring
Profile Headlinefrs_profile_headlinestring
Profile Themefrs_profile_themestring
Is Activefrs_is_activeboolean
QR Code Datafrs_qr_code_datastring

JSON Array Fields

FieldMeta Key
Specialtiesfrs_specialties
LO Specialtiesfrs_specialties_lo
Languagesfrs_languages
Custom Linksfrs_custom_links

Sync Fields

FieldMeta Key
Company Rolefrs_company_role (multi-value)
Person Typefrs_select_person_type
Agent IDfrs_agent_id
FluentCRM Syncedfrs_synced_to_fluentcrm_at

Site Contexts

Set via FRS_SITE_CONTEXT constant in wp-config.php to control which roles are visible per site.

ContextCompany RolesCan Edit
developmentAll 8 rolesYes
hubAll 8 rolesYes
21stcenturylendingloan_originator, leadershipNo
c21mastersbroker_associate, sales_associate, leadershipNo

Precedence: Constant → Filter (frs_site_context) → Option → Default (development)

php
// wp-config.php
define('FRS_SITE_CONTEXT', '21stcenturylending');

FluentCRM Integration

Real-time sync between profiles and FluentCRM contacts on user create/update/role change.

Sync Triggers

  • Profile create → Create FluentCRM contact
  • Profile update → Update FluentCRM contact
  • Role change → Update FluentCRM tags
  • Profile delete → Remove tags (contact preserved)

Tag Mapping

Company RoleFluentCRM Tag
loan_originatorLoan Originator
broker_associateBroker Associate
sales_associateSales Associate
leadershipLeadership
staffStaff

Configuration

FluentCRM runs on main site only in multisite. Configure site ID:

php
// wp-config.php
define('FRS_FLUENTCRM_SITE_ID', 1);

Integrations

Simple Local Avatars

Headshot management using Simple Local Avatars plugin for avatar storage.

Arrive Auto-Populate

Auto-populates loan application URLs for loan officers based on their NMLS number.


Planned Features

Coming Soon

The following features are planned but not yet implemented.

Follow Up Boss Integration

CRM integration for syncing profiles to Follow Up Boss on save.

WordPress Abilities API

AI-ready abilities for profile queries:

  • frs-users/list-profiles - Query profiles with filters
  • frs-users/get-profile - Get single profile by ID
  • frs-users/search-profiles - Full-text search

Hooks & Filters

Actions

HookDescriptionArguments
frs_profile_savedAfter profile save$profile_id, $profile_data
frs_users_loadedAfter plugin init(none)
frs_users_api_routesAdd custom REST routes(none)
php
// After profile saved
add_action('frs_profile_saved', function($profile_id, $profile_data) {
    // Trigger external sync, notifications, etc.
}, 10, 2);

Filters

HookDescriptionArguments
frs_site_contextOverride site context$context
php
// Override site context dynamically
add_filter('frs_site_context', function($context) {
    if (is_page('lending')) {
        return '21stcenturylending';
    }
    return $context;
});

CLI Commands

bash
# Check site context
wp frs-users site-context

# Setup sync between hub and marketing sites
wp frs-users setup-sync --hub-url=https://myhub21.com
wp frs-users setup-sync --generate-secret

# Sync profiles from hub
wp frs-users sync-from-hub [--type=loan_originator] [--dry-run]

# List profiles
wp frs-users list-profiles [--type=loan_originator]
wp frs-users list-guests

# Profile utilities
wp frs-users create-user <profile_id>
wp frs-users generate-slugs
wp frs-users generate-qr-codes [--force]
wp frs-users generate-vcards [--type=loan_originator]

# Migrations
wp frs-users migrate-fields [--dry-run]
wp frs-users cleanup-fields [--dry-run]

Admin Pages

PageLocation
All ProfilesUsers → FRS Profiles
Add ProfileUsers → Add FRS Profile
Edit ProfileUsers → FRS Profiles → Edit
Import/ExportUsers → Import/Export

Code Examples

Get Profile by User ID

php
use FRSUsers\Models\Profile;

$profile = Profile::get_by_user_id($user_id);
if ($profile) {
    echo $profile->get('first_name');
    echo $profile->get('frs_nmls_id');
}

Create Profile

php
use FRSUsers\Models\Profile;

$profile = new Profile();
$profile->set('user_id', $user_id);
$profile->set('first_name', 'John');
$profile->set('last_name', 'Doe');
$profile->set('frs_role', 'loan_officer');
$profile->save();

Query Profiles

php
use FRSUsers\Core\ProfileApi;

$api = ProfileApi::get_instance();
$profiles = $api->get_profiles([
    'role' => 'loan_officer',
    'department' => 'Sales',
    'per_page' => 20
]);

File Structure

frs-wp-users/
├── frs-wp-users.php          # Main plugin file
├── plugin.php                # Plugin class
├── includes/
│   ├── Core/                 # Core services
│   │   ├── Roles.php         # Role/context configuration
│   │   ├── ProfileApi.php    # REST API handler
│   │   ├── ProfileStorage.php
│   │   ├── ProfileSync.php   # Webhook synchronization
│   │   ├── CLI.php           # WP-CLI commands
│   │   └── Template.php      # URL routing
│   ├── Models/               # Data models
│   │   ├── Profile.php
│   │   └── UserProfile.php
│   ├── Admin/                # Admin pages (DataViews-based)
│   │   ├── ProfilesAdminPage.php
│   │   ├── ProfileEditPage.php
│   │   └── CsvImportExport.php
│   ├── Controllers/          # Blocks, shortcodes
│   ├── Routes/               # REST API
│   │   └── Api.php
│   ├── Integrations/         # External services
│   │   ├── FluentCRMSync.php
│   │   └── ArriveAutoPopulate.php
│   ├── Abilities/            # WordPress Abilities API (planned)
│   └── Intranet/             # Intranet module (planned)
├── assets/
│   ├── admin/                # React admin interface
│   └── blocks/               # Gutenberg blocks
├── templates/profile/        # Frontend templates
└── database/Migrations/      # Schema migrations

Hub21 Platform Documentation