MksDdn Forms Handler is a powerful and flexible form processing plugin that allows you to create and manage forms with multiple delivery methods. Perfect for websites that need reliable form handling with modern integrations.
Key Features
- Multiple Delivery Methods: Send form submissions via email, Telegram, Google Sheets, or store in WordPress admin
- REST API Support: Submit forms via AJAX or REST API endpoints
- Telegram Integration: Instant notifications to Telegram channels
- Google Sheets Integration: Automatically save submissions to Google Sheets
- Custom Post Types: Dedicated forms and submissions management
- Security First: Built-in validation, sanitization, and security measures
- Developer Friendly: Clean code structure with proper namespacing
Use Cases
- Contact forms with multiple delivery options
- Lead generation forms with instant notifications
- Data collection forms with Google Sheets backup
- Custom forms with REST API integration
Technical Features
- WordPress 5.0+ compatible (tested up to 6.9)
- PHP 8.0+ required
- GPL v2+ licensed
- Clean, maintainable code
- Proper error handling
- Comprehensive logging
For Developers
Architecture
Component-based structure following SOLID principles with clear separation of concerns:
Core Components (includes/)
* PostTypes – custom post types registration (mksddn_fh_forms, mksddn_fh_submits)
* MetaBoxes – form settings and submission data management
* FormsHandler – main processing logic with REST API support
* Shortcodes – form rendering with AJAX functionality
* AdminColumns – admin interface customization
* ExportHandler – CSV export with filtering
* Security – rate limiting and security checks
* Utilities – helper functions and form creation utilities
* GoogleSheetsAdmin – Google Sheets settings page and OAuth
* Assets – asset registration and conditional enqueuing
* Template Functions – global functions for PHP template integration
Handlers (handlers/)
* TelegramHandler – Telegram Bot API integration
* GoogleSheetsHandler – Google Sheets API integration
Assets (assets/)
* css/ – Admin and frontend styles
* js/ – Admin and form scripts
* images/ – Plugin images
Technology Stack
- WordPress 5.0+ – core platform
- PHP 8.0+ – server-side logic
- jQuery – client-side form handling
- REST API – form submission API
- Google Sheets API – spreadsheet integration
- Telegram Bot API – notifications
File Structure
mksddn-forms-handler/
├── mksddn-forms-handler.php # Main plugin file
├── includes/ # Core components
│ ├── class-post-types.php
│ ├── class-meta-boxes.php
│ ├── class-forms-handler.php
│ ├── class-shortcodes.php
│ ├── class-admin-columns.php
│ ├── class-export-handler.php
│ ├── class-security.php
│ ├── class-utilities.php
│ ├── class-google-sheets-admin.php
│ ├── class-assets.php
│ └── template-functions.php
├── handlers/ # External service handlers
│ ├── class-telegram-handler.php
│ └── class-google-sheets-handler.php
├── templates/ # Template files
│ ├── form-settings-meta-box.php
│ └── custom-form-examples.php
├── assets/ # Static resources
│ ├── css/
│ ├── js/
│ └── images/
├── languages/ # Translations
└── uninstall.php # Cleanup script
Integration Methods
1. Shortcode (Standard)
[mksddn_fh_form slug="contact-form"]
Plugin automatically generates HTML form based on configuration.
2. PHP Templates (Custom Forms)
Integrate pre-built forms in theme templates:
<form method="post" action="<?php echo mksddn_fh_get_form_action(); ?>">
<?php mksddn_fh_form_fields('contact-form'); ?>
<!-- Your custom fields -->
<input type="text" name="name" required>
<input type="email" name="email" required>
<button type="submit">Send</button>
</form>
Available Functions:
* mksddn_fh_get_form_action() – get form action URL
* mksddn_fh_form_fields($slug) – output hidden fields (nonce, form_id, honeypot)
* mksddn_fh_get_form_config($slug) – get form configuration
* mksddn_fh_get_rest_endpoint($slug) – get REST API endpoint for AJAX
* mksddn_fh_form_has_files($slug) – check for file fields
* mksddn_fh_enqueue_form_script() – enqueue AJAX script
Accept Any Fields (Advanced):
For custom forms where you control field names in templates, enable “Accept any fields from frontend” in form settings to skip field validation. This allows submitting ANY field names without defining them in Fields Configuration. All fields are still sanitized but type validation is skipped.
See /templates/custom-form-examples.php for detailed examples.
3. REST API (AJAX)
Submit forms via REST API without page reload:
fetch('<?php echo mksddn_fh_get_rest_endpoint("contact-form"); ?>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
Development Standards
Coding
* WordPress Coding Standards compliance
* SOLID principles
* DRY (Don’t Repeat Yourself)
* KISS (Keep It Simple)
Security
* Input validation for all data
* Output sanitization
* Nonce verification (CSRF protection)
* Capability checks
* Rate limiting (1 request per 10 seconds per IP per form)
Performance
* Minimal database queries
* Data caching
* Lazy loading of resources
* Conditional script enqueuing
Compatibility
* WordPress 5.0+ minimum
* PHP 8.0+ minimum
* Multisite support
* RTL support
* Accessibility standards (WCAG)
WordPress Hooks & Filters
Filters:
mksddn_fh_allowed_fields - Modify allowed field names for a form
add_filter('mksddn_fh_allowed_fields', function($allowed_fields, $form_id, $form_slug) {
// Allow all fields for specific form
if ($form_slug === 'my-custom-form') {
return ['*'];
}
// Add specific fields
return array_merge($allowed_fields, ['custom_field_1', 'custom_field_2']);
}, 10, 3);
mksddn_fh_allowed_redirect_hosts - Whitelist external domains for redirect URLs
add_filter('mksddn_fh_allowed_redirect_hosts', function($hosts) {
// Allow specific external domains for redirects
return array_merge($hosts, ['example.com', 'trusted-partner.com']);
});
Actions:
mksddn_forms_handler_log_security - Fired when unauthorized fields are detected
mksddn_forms_handler_log_submission - Fired when form submission is processed<h3>REST API</h3>
Namespace: mksddn-forms-handler/v1
List Forms
- Method: GET
- Path:
/wp-json/mksddn-forms-handler/v1/forms - Query Parameters:
per_page(1–100, default: 10)page(>=1, default: 1)search(string, optional)
- Response Headers:
X-WP-Total,X-WP-TotalPages
Get Single Form
- Method: GET
- Path:
/wp-json/mksddn-forms-handler/v1/forms/{slug} - Response: Includes
id,slug,title,submit_url,fields(sanitized config)
Submit Form
- Method: POST
- Path:
/wp-json/mksddn-forms-handler/v1/forms/{slug}/submit - Content Types: JSON or multipart/form-data
- Body (JSON): Key/value pairs according to field configuration. The
mksddn_fh_hphoneypot field may be present and must be empty (spam protection). - Body (Multipart): Fields and file uploads supported. For multiple files, use
name[].
Validation & Limits
- Only configured fields accepted; unauthorized fields return
unauthorized_fieldserror - Required fields, email, URL, number (min/max/step), tel (pattern), date, time, datetime-local are validated
- Maximum 50 fields; total payload size ≤ 100 KB
- Rate limiting: 1 request per 10 seconds per IP per form
Examples
List forms:
curl -s 'https://example.com/wp-json/mksddn-forms-handler/v1/forms'
Get single form:
curl -s 'https://example.com/wp-json/mksddn-forms-handler/v1/forms/contact'
Submit form (JSON):
curl -s -X POST \
-H 'Content-Type: application/json' \
-d '{"name":"John","email":"john@example.com","message":"Hi","mksddn_fh_hp":""}' \
'https://example.com/wp-json/mksddn-forms-handler/v1/forms/contact/submit'
Submit form with files (multipart):
curl -s -X POST \
-F 'name=John' \
-F 'email=john@example.com' \
-F 'attachments[]=@/path/to/file1.pdf' \
-F 'attachments[]=@/path/to/file2.png' \
'https://example.com/wp-json/mksddn-forms-handler/v1/forms/contact/submit'<h3>Supported Field Types</h3>
Fields are configured as JSON in the form settings. Supported types:
- Basic: text, email, password
- Input: tel, url, number, date, time, datetime-local
- Text: textarea
- Choice: checkbox, select (supports multiple), radio
- File: file uploads (form and REST multipart)
- Array: array_of_objects – array of objects with nested field validation
Field Configuration Notes
name– field name (required, used as form input name)label– field label displayed in forms and admin (optional, falls back toname)notification_label– custom label for Telegram/email notifications (optional, priority: notification_label label name)type– field type (required)required– whether field is required (boolean, default: false)optionscan be an array of strings or objects{ "value": "...", "label": "..." }- For
selectwith multiple choice, setmultiple: true(shortcode rendersname[]) - For
number, optional attributes:min,max,step - For
tel, optionalpattern(default server validation uses^\+?\d{7,15}$) - For
date/time/datetime-local, server validates formats:YYYY-MM-DD,HH:MM,YYYY-MM-DDTHH:MM - For REST submissions, send arrays for multiple selects
- Pattern validation: use standard regex syntax (backslashes are preserved, invalid patterns are rejected)
File Field Options
allowed_extensions: Array of extensions, e.g.["pdf","png","jpg"]max_size_mb: Maximum size per file (default: 10)max_files: Maximum files per field (default: 5)multiple: Allow multiple files
Example JSON Configuration
[
{"name":"name","label":"Name","type":"text","required":true,"placeholder":"Your name"},
{"name":"email","label":"Email","notification_label":"Email Address","type":"email","required":true},
{"name":"phone","label":"Phone","type":"tel","pattern":"^\\\\+?\\\\d{7,15}$"},
{"name":"website","label":"Website","type":"url"},
{"name":"age","label":"Age","type":"number","min":1,"max":120,"step":1},
{"name":"birth","label":"Birth date","type":"date"},
{"name":"message","label":"Message","type":"textarea","required":true},
{"name":"agree","label":"I agree to Terms","type":"checkbox","required":true},
{
"name":"services",
"label":"Choose services",
"type":"select",
"multiple":true,
"options":["seo","smm","ads"]
},
{
"name":"attachments",
"label":"Attach files",
"type":"file",
"multiple":true,
"allowed_extensions":["pdf","png","jpg"],
"max_size_mb":10,
"max_files":3
},
{
"name":"products",
"label":"Products",
"type":"array_of_objects",
"required":true,
"fields":[
{"name":"name","label":"Product Name","type":"text","required":true},
{"name":"size","label":"Size","type":"text","required":true},
{"name":"color","label":"Color","type":"text","required":true},
{"name":"quantity","label":"Quantity","type":"number","required":true,"min":1},
{"name":"price","label":"Price","type":"number","required":true,"min":0}
]
}
]
Pattern Validation Examples
Common regex patterns for validation (use in JSON with double backslashes):
- Phone (international):
"pattern": "^\\+?\\d{7,15}$" - Phone (US):
"pattern": "^\\(\\d{3}\\)\\s?\\d{3}-\\d{4}$" - Postal code (US):
"pattern": "^\\d{5}(-\\d{4})?$" - Postal code (RU):
"pattern": "^\\d{6}$" - Only letters:
"pattern": "^[a-zA-Z]+$" - Alphanumeric:
"pattern": "^[a-zA-Z0-9]+$" - URL slug:
"pattern": "^[a-z0-9-]+$"
Important notes:
* In JSON, backslashes must be doubled (e.g., \\d instead of \d, \\+ instead of \+)
* HTML tags in patterns will be automatically removed for security
* Invalid regex patterns will be rejected silently (check debug.log if WP_DEBUG is enabled)
Array of Objects Field Type
The array_of_objects type allows you to define arrays with nested field validation. Each item in the array is validated according to the nested fields configuration.
Configuration:
* name: Field name (required)
* label: Field label (required)
* notification_label: Custom label for notifications (optional, priority: notification_label label name)
* type: Must be "array_of_objects" (required)
* required: Whether the array is required (default: false)
* fields: Array of field configurations for each object in the array (required)
Nested fields support all standard field types (text, email, tel, url, number, textarea, etc.) with full validation. Nested fields also support notification_label for custom labels in Telegram/email notifications.
Example REST API submission:
{
"email": "user@example.com",
"phone": "+1234567890",
"products": [
{
"name": "T-Shirt",
"size": "M",
"color": "Red",
"quantity": 2,
"price": 1500
},
{
"name": "Jeans",
"size": "L",
"color": "Blue",
"quantity": 1,
"price": 3000
}
]
}<h3>External Services</h3>
This plugin can connect to external services when explicitly enabled in a form’s settings:
Google OAuth2 and Google Sheets API
- Purpose: Authenticate and append rows to a spreadsheet
- When: Only if “Send to Google Sheets” is enabled for a form and valid credentials are provided
- Data sent: Form fields configured for the form, form title, timestamp
- Endpoints used:
https://oauth2.googleapis.com/token,https://sheets.googleapis.com/v4/spreadsheets/... - Terms: https://policies.google.com/terms
- Privacy: https://policies.google.com/privacy
Telegram Bot API
- Purpose: Send a message with submission content to specified chat(s)
- When: Only if “Send to Telegram” is enabled for a form and bot token + chat IDs are configured
- Data sent: Form fields configured for the form, form title
- Endpoint used:
https://api.telegram.org/bot<token>/sendMessage - Terms/Privacy: https://telegram.org/privacy
Privacy Notes
- No IP address or user agent is transmitted to external services; only form field values are sent
- External delivery is opt-in per form and disabled by default