Complete guide to setting up a new client plugin using the SMPLFY Core Plugin.
- SMPLFY Core Plugin installed and activated
- Access to Gravity Forms admin
- Basic understanding of PHP and WordPress
- Code editor with PHP support
cd /path/to/wp-content/plugins/
git clone https://github.com/sblik/smplfy-boilerplate-plugin.git client-name-plugin
cd client-name-pluginRename plugin folder and main file:
mv smplfy-boilerplate-plugin.php client-name-plugin.phpUpdate plugin header in client-name-plugin.php:
/**
* Plugin Name: Client Name Custom Plugin
* Description: Custom business automation for Client Name
* Version: 1.0.0
* Author: Your Team Name
*/Update namespace throughout all files:
- Find:
SMPLFY\boilerplate - Replace:
SMPLFY\ClientName
Files to update:
- All PHP files in
/public/php/ - Main plugin file
- Go to WordPress Admin → Forms
- Note the forms you'll be working with
- Hover over each form to see its ID in the URL
Example:
- Contact Form → ID: 5
- Application Form → ID: 12
- Order Form → ID: 18
Edit /public/php/types/FormIds.php:
<?php
namespace SMPLFY\ClientName;
class FormIds {
const CONTACT_FORM_ID = 5;
const APPLICATION_FORM_ID = 12;
const ORDER_FORM_ID = 18;
}For each form:
- Open form in Form Editor
- Click on each field
- Note the Field ID in the settings panel
- For name fields, note sub-field IDs (1.3, 1.6, etc.)
Create a mapping document:
| Form | Field Label | Field ID | Property Name |
|---|---|---|---|
| Contact (5) | First Name | 1.3 | nameFirst |
| Contact (5) | Last Name | 1.6 | nameLast |
| Contact (5) | 2 | ||
| Contact (5) | Phone | 3 | phone |
| Contact (5) | Company | 4 | company |
See Finding Form & Field IDs for detailed instructions.
For each form, create an entity class.
Example: Contact Form Entity
Create /public/php/entities/ContactFormEntity.php:
<?php
namespace SMPLFY\ClientName;
use SmplfyCore\SMPLFY_BaseEntity;
/**
* @property string $nameFirst
* @property string $nameLast
* @property string $email
* @property string $phone
* @property string $company
*/
class ContactFormEntity extends SMPLFY_BaseEntity {
public function __construct($formEntry = array()) {
parent::__construct($formEntry);
$this->formId = FormIds::CONTACT_FORM_ID;
}
protected function get_property_map(): array {
return [
'nameFirst' => '1.3',
'nameLast' => '1.6',
'email' => '2',
'phone' => '3',
'company' => '4',
];
}
}Repeat for each form.
For each entity, create a repository class.
Example: Contact Form Repository
Create /public/php/repositories/ContactFormRepository.php:
<?php
namespace SMPLFY\ClientName;
use SmplfyCore\SMPLFY_BaseRepository;
use SmplfyCore\SMPLFY_GravityFormsApiWrapper;
use WP_Error;
/**
* @method static ContactFormEntity|null get_one($fieldId, $value)
* @method static ContactFormEntity|null get_one_for_current_user()
* @method static ContactFormEntity|null get_one_for_user($userId)
* @method static ContactFormEntity[] get_all($fieldId = null, $value = null, string $direction = 'ASC')
* @method static int|WP_Error add(ContactFormEntity $entity)
*/
class ContactFormRepository extends SMPLFY_BaseRepository {
public function __construct(SMPLFY_GravityFormsApiWrapper $gravityFormsApi) {
$this->entityType = ContactFormEntity::class;
$this->formId = FormIds::CONTACT_FORM_ID;
parent::__construct($gravityFormsApi);
}
}Repeat for each form.
Create use cases for your business logic.
Example: Contact Form Submission Use Case
Create /public/php/usecases/ContactFormSubmissionUsecase.php:
<?php
namespace SMPLFY\ClientName;
use SmplfyCore\SMPLFY_Log;
class ContactFormSubmissionUsecase {
private ContactFormRepository $contactRepository;
public function __construct(ContactFormRepository $contactRepository) {
$this->contactRepository = $contactRepository;
}
public function handle_submission($entry) {
$entity = new ContactFormEntity($entry);
// Log submission
SMPLFY_Log::info("Contact form submitted", [
'email' => $entity->email,
'name' => $entity->nameFirst . ' ' . $entity->nameLast
]);
// Add your business logic here
// - Send to CRM
// - Send email notification
// - Update other records
// - etc.
}
}Create an adapter to hook your use cases into Gravity Forms.
Example: Gravity Forms Adapter
Create /public/php/adapters/GravityFormsAdapter.php:
<?php
namespace SMPLFY\ClientName;
class GravityFormsAdapter {
private ContactFormSubmissionUsecase $contactSubmissionUsecase;
public function __construct(ContactFormSubmissionUsecase $contactSubmissionUsecase) {
$this->contactSubmissionUsecase = $contactSubmissionUsecase;
}
public function register_hooks() {
add_action(
'gform_after_submission_' . FormIds::CONTACT_FORM_ID,
[$this->contactSubmissionUsecase, 'handle_submission'],
10,
2
);
}
}In your main plugin file, instantiate and wire up dependencies:
<?php
// After the plugin header comment
// Security check
if (!defined('ABSPATH')) {
exit;
}
// Load utilities
require_once plugin_dir_path(__FILE__) . '../smplfy-core-plugin/includes/utilities.php';
// Load all classes
require_utilities(__DIR__ . '/public/php/types');
require_utilities(__DIR__ . '/public/php/entities');
require_utilities(__DIR__ . '/public/php/repositories');
require_utilities(__DIR__ . '/public/php/usecases');
require_utilities(__DIR__ . '/public/php/adapters');
// Initialize plugin
add_action('plugins_loaded', function() {
$gravityFormsApi = new SmplfyCore\SMPLFY_GravityFormsApiWrapper();
// Repositories
$contactRepository = new SMPLFY\ClientName\ContactFormRepository($gravityFormsApi);
// Use Cases
$contactSubmissionUsecase = new SMPLFY\ClientName\ContactFormSubmissionUsecase(
$contactRepository
);
// Adapters
$gfAdapter = new SMPLFY\ClientName\GravityFormsAdapter(
$contactSubmissionUsecase
);
// Register hooks
$gfAdapter->register_hooks();
}, 20);- Submit a test form in WordPress
- Check Datadog logs (if enabled)
- Verify entry was created in Gravity Forms
- Check that use case logic executed correctly
Add this to your use case temporarily:
public function handle_submission($entry) {
$entity = new ContactFormEntity($entry);
// Debug output
error_log("Email: " . $entity->email);
error_log("Name: " . $entity->nameFirst . " " . $entity->nameLast);
error_log("Full entry: " . print_r($entity->to_array(), true));
}Use WP-CLI to test repository methods:
# Get all entries
wp eval "print_r((new SMPLFY\ClientName\ContactFormRepository(new SmplfyCore\SMPLFY_GravityFormsApiWrapper()))->get_all());"
# Get specific entry
wp eval "\$repo = new SMPLFY\ClientName\ContactFormRepository(new SmplfyCore\SMPLFY_GravityFormsApiWrapper()); \$entity = \$repo->get_one('email', 'test@example.com'); print_r(\$entity->to_array());"Error: Class 'SMPLFY\boilerplate\FormIds' not found
Solution: You missed updating a namespace. Search all files for SMPLFY\boilerplate and replace with SMPLFY\ClientName.
Error: $entity->email returns null but field has data
Solution:
- Check field ID is correct in GF admin
- Ensure field ID is a string:
'2'not2 - For name fields, use sub-field ID:
'1.3'
Error: Use case doesn't execute on form submission
Solution:
- Verify form ID is correct in
FormIds.php - Check adapter's
register_hooks()is called - Verify hook name:
gform_after_submission_5(with form ID) - Check plugin is activated
Error: Class 'SMPLFY\ClientName\ContactFormEntity' not found
Solution:
- Verify
require_utilities()is loading the entity directory - Check file name matches class name:
ContactFormEntity.php - Verify namespace in file matches directory structure
Once your plugin is working:
- Add more forms - Create entities/repositories for remaining forms
- Add business logic - Implement use cases for form submissions
- Integrate Gravity Flow - Add workflow step transitions
- Add external integrations - Connect to CRMs, email services, etc.
- Enable Datadog - Configure logging for production monitoring
Use this checklist for each new client site:
- Cloned boilerplate plugin
- Renamed plugin folder and main file
- Updated plugin header
- Updated all namespaces
- Created FormIds constants
- Documented all field IDs
- Created entity for each form
- Created repository for each form
- Created use cases for business logic
- Created adapters for hook registration
- Wired dependencies in main file
- Tested form submission
- Verified logging works
- Deployed to staging
- Tested on staging
- Deployed to production
- Entities - Creating and using entities
- Repositories - Working with repositories
- Use Cases - Organizing business logic
- Finding IDs - How to find form and field IDs
- Debugging - Troubleshooting guide