Trongate PHP Framework Docs
Introduction
Basic Concepts
Understanding Routing
Intercepting Requests
Module Fundamentals
Database Operations
Templates
Helpers
Form Handling
Form Validation
Working With Files
Image Manipulation
Working With Dates & Times
Language Control
Authorization & Authentication
Tips And Best Practices

Custom Validation Rules

For validation logic beyond the built-in rules, create custom validation callbacks. Creating your own custom validation callbacks gives you unlimited flexibility while maintaining Trongate's security-first approach.

The Pattern

Custom validation uses the callback_ prefix in rules, with secured methods protected by :

  1. Add callback_method_name to your validation rules
  2. Create a method that receives the field value
  3. Call block_url('module/method') at the start to prevent direct URL access
  4. Return true (pass) or an error string (fail)

Security First: Validation callback methods should call block_url() to prevent direct URL access. This protects your validation logic from being invoked outside the validation flow.

Input is Pre-Cleaned: The value passed to your callback method has already been processed by the helper function, specifically with post($field, true). This means whitespace is trimmed and multiple spaces are collapsed.

Therefore, within your form validation callback methods, you don't need to clean the input again - just validate it.

Basic Example

When the form is submitted with a username that already exists in the database, the error message displays: "The username is already taken." The {label} placeholder is automatically replaced with the field label you defined in set_rules().

How It Works

When validation runs:

  1. Validation system retrieves field value using post($field, true) (cleaned and trimmed)
  2. Trongate sees callback_method_name in the validation rules
  3. Calls the method with the cleaned field value
  4. The method calls block_url('module/method') to secure the endpoint
  5. If method returns a string: Validation fails, string becomes error message (with {label} substitution if present)
  6. If method returns true: Validation passes

Return Values

Return Result Example
true Validation passes return true;
String (error message) Validation fails with custom message return 'Invalid format.';
String with {label} Fails with label substitution return 'The {label} must be unique.';

Important: Validation callback methods must only return either true or a string.

Custom validation callback methods must never return false, null, or other values.

Real-World Examples

For the examples below, we'll assume the code exists in a controller file named Members.php (in a members module).

Security Tip: Protect your custom validation callbacks from direct URL access by calling at the start of each method.

In those instances, pass the module name and method name as a single string, separated by a forward slash. For example: block_url('members/method_name').

Username Validation (Create and Update)

Allow usernames only during creation, or allow existing username to remain unchanged during updates:

Key insights: This example handles both creation and updates. When creating ($update_id === 0), any existing username fails. When updating, the existing username is allowed only if it belongs to the same user being edited.

Email Uniqueness with Security

For sensitive fields like email, use generic error messages to prevent account enumeration attacks:

Security note: Notice how the error message doesn't say "email already exists" - it uses a generic message instead. This prevents attackers from using the validation system to enumerate valid email addresses.

Discount Code Validation

Check if a discount code exists and is valid before allowing form submission:

Product Code Validation

Verify a product code exists in inventory and is not discontinued:

Sale Price Validation

Ensure a sale price is less than the original price:

Checkbox Agreement Validation

Require users to agree to terms or confirm they meet age requirements:

Note: Checkboxes return '1' when checked and an empty string when unchecked. We explicitly cast to string for type consistency.

External API Validation

Call an external service to validate data. For example, verify a phone number with a telecom API:

Conditional Logic Validation

Validate one field based on the value of another field. For example, require "other reason" only if "reason" is set to "other":

Complex Business Logic Validation

Validate against multiple conditions that represent your business rules. For example, ensure a user has sufficient credits before allowing a purchase:

  1. Always secure your callback methods: Call block_url('module/method') at the start of each callback to prevent direct URL access.
  2. Use correct block_url() syntax: Pass the module name and method name separated by a forward slash: block_url('members/username_check').
  3. Don't clean input: Input is already cleaned by post($field, true) - no need to trim or process again.
  4. Handle empty optional fields: Return true for optional fields when the value is an empty string.
  5. Use framework database helpers: Prefer get_one_where() over manual query_bind() for simple queries.
  6. Explicit comparisons: Use !== false for database result checks to distinguish between "no results" and "actual data."
  7. Use {label} appropriately: Use {label} placeholders where they create natural, readable phrasing.
  8. Security-conscious messages: For sensitive data (emails, usernames, accounts), use generic error messages to prevent enumeration attacks.
  9. Type consistency: Convert checkbox values to string for consistent comparison: $value = (string) $value.
  10. Type hints (recommended): Add parameter and return type hints for clarity: function callback(string $value): string|bool.
  11. Descriptive names: Use clear method names like email_unique or verify_phone_number, not check1.
  12. Document your callbacks: Add PHPDoc comments explaining what the callback validates and what it returns.

Always use parameterized queries or framework helpers: Use or with placeholders. Never concatenate user input directly into SQL queries.

Framework Security Features: By following Trongate validation patterns, you automatically get:

  • Automatic URL blocking - via block_url()
  • Pre-cleaned input - Values are processed by post($field, true) before reaching callbacks
  • Built-in SQL injection prevention - Framework helpers use parameterized queries
  • CSRF protection - Automatic token validation on form submissions
  • Session-based validation - Errors survive redirects and display appropriately
  • Zero configuration security - Works automatically when patterns are followed