Built-in Conditions Reference
MilliRules comes with a comprehensive set of built-in conditions for both framework-agnostic PHP applications and WordPress-specific scenarios. This reference guide documents every available condition with examples and usage patterns.
Condition Packages#
Conditions are organized into packages:
- PHP Package - Framework-agnostic HTTP and request conditions (always available)
- WordPress Package - WordPress-specific conditions (available only in WordPress)
PHP Package Conditions#
The PHP package provides framework-agnostic conditions that work in any PHP 7.4+ environment. These conditions handle HTTP requests, headers, cookies, and parameters.
request_url#
Check the request URL or URI path against a pattern or value.
Namespace: MilliRulesPackagesPHPConditionsRequestUrl
Signature:
1->request_url($value, $operator = '=')
Parameters:
$value(string|array): URL pattern or array of patterns$operator(string): Comparison operator (default:'=')
Supported Operators: All operators (=, !=, LIKE, REGEXP, IN, NOT IN, EXISTS, etc.)
Context Data Used: $context->get('request.uri', '')
Examples
Exact match:
1Rules::create('exact_url')
2 ->when()
3 ->request_url('/wp-admin/edit.php') // Exact URL match
4 ->then()->custom('action')
5 ->register();
Wildcard pattern matching:
1Rules::create('admin_urls')
2 ->when()
3 ->request_url('/wp-admin/*', 'LIKE') // Matches any admin URL
4 ->then()->custom('action')
5 ->register();
6
7// Auto-detected LIKE operator (has wildcard)
8Rules::create('api_urls')
9 ->when()
10 ->request_url('/api/*') // LIKE operator auto-detected
11 ->then()->custom('action')
12 ->register();
Multiple URL patterns:
1Rules::create('protected_areas')
2 ->when()
3 ->request_url([
4 '/wp-admin/*',
5 '/wp-login.php',
6 '/dashboard/*'
7 ], 'IN')
8 ->then()->custom('check_authentication')
9 ->register();
Regex matching:
1Rules::create('api_versioned')
2 ->when()
3 // Matches /api/v1/, /api/v2/, etc.
4 ->request_url('/^\/api\/v[0-9]+\//i', 'REGEXP')
5 ->then()->custom('route_api_request')
6 ->register();
Exclude patterns:
1Rules::create('non_admin_urls')
2 ->when()
3 ->request_url('/wp-admin/*', 'NOT LIKE') // Not admin URLs
4 ->then()->custom('public_action')
5 ->register();
* matches anything, ? matches single character) for flexible pattern matching without the complexity of regex.request_method#
Check the HTTP request method (GET, POST, PUT, DELETE, etc.).
Namespace: MilliRulesPackagesPHPConditionsRequestMethod
Signature:
1->request_method($value, $operator = '=')
Parameters:
$value(string|array): HTTP method(s) to check$operator(string): Comparison operator (default:'=')
Supported Operators: =, !=, IN, NOT IN, EXISTS
Context Data Used: $context->get('request.method', '')
Examples
Single method:
1Rules::create('post_requests')
2 ->when()
3 ->request_method('POST') // Only POST requests
4 ->then()->custom('process_form')
5 ->register();
Multiple methods (OR logic):
1Rules::create('safe_methods')
2 ->when()
3 ->request_method(['GET', 'HEAD'], 'IN') // GET or HEAD
4 ->then()->custom('enable_caching')
5 ->register();
6
7// Auto-detected IN operator (array value)
8Rules::create('safe_methods_auto')
9 ->when()
10 ->request_method(['GET', 'HEAD']) // IN auto-detected
11 ->then()->custom('enable_caching')
12 ->register();
Exclude methods:
1Rules::create('non_post_requests')
2 ->when()
3 ->request_method('POST', '!=')
4 ->then()->custom('action')
5 ->register();
6
7Rules::create('non_modifying_requests')
8 ->when()
9 ->request_method(['POST', 'PUT', 'DELETE', 'PATCH'], 'NOT IN')
10 ->then()->custom('read_only_action')
11 ->register();
'POST' and 'post' work identically.request_header#
Check request headers against expected values.
Namespace: MilliRulesPackagesPHPConditionsRequestHeader
Signature:
1->request_header($header_name, $value = null, $operator = '=')
Parameters:
$header_name(string): Header name (case-insensitive)$value(mixed): Expected value (null to check existence)$operator(string): Comparison operator (default:'=')
Supported Operators: All operators
Context Data Used: $context['request']['headers'][$header_name]
Examples
Check header existence:
1Rules::create('has_auth_header')
2 ->when()
3 ->request_header('Authorization') // Header exists
4 ->then()->custom('process_authenticated')
5 ->register();
Check header value:
1Rules::create('json_requests')
2 ->when()
3 ->request_header('Content-Type', 'application/json')
4 ->then()->custom('parse_json')
5 ->register();
Pattern matching headers:
1Rules::create('bearer_token')
2 ->when()
3 ->request_header('Authorization', 'Bearer *', 'LIKE')
4 ->then()->custom('validate_token')
5 ->register();
Multiple accepted values:
1Rules::create('json_or_xml')
2 ->when()
3 ->request_header('Content-Type', [
4 'application/json',
5 'application/xml',
6 'text/xml'
7 ], 'IN')
8 ->then()->custom('parse_structured_data')
9 ->register();
Regex for complex matching:
1Rules::create('api_key_format')
2 ->when()
3 ->request_header('X-API-Key', '/^[A-Za-z0-9]{32}$/', 'REGEXP')
4 ->then()->custom('validate_api_key')
5 ->register();
'Content-Type', 'content-type', and 'CONTENT-TYPE' all reference the same header.request_param#
Check URL query parameters or form POST data.
Namespace: MilliRulesPackagesPHPConditionsRequestParam
Signature:
1->request_param($param_name, $value = null, $operator = '=')
Parameters:
$param_name(string): Parameter name$value(mixed): Expected value (null to check existence)$operator(string): Comparison operator (default:'=')
Supported Operators: All operators
Context Data Used: $context['request']['params'][$param_name] (merges $_GET and $_POST)
Examples
Check parameter existence:
1Rules::create('has_action_param')
2 ->when()
3 ->request_param('action') // Parameter exists
4 ->then()->custom('route_action')
5 ->register();
Check parameter value:
1Rules::create('delete_action')
2 ->when()
3 ->request_param('action', 'delete')
4 ->then()->custom('confirm_delete')
5 ->register();
Numeric comparison:
1Rules::create('pagination')
2 ->when()
3 ->request_param('page', '1', '>') // Page > 1
4 ->then()->custom('show_pagination')
5 ->register();
Multiple accepted values:
1Rules::create('list_actions')
2 ->when()
3 ->request_param('view', ['list', 'grid', 'table'], 'IN')
4 ->then()->custom('render_list_view')
5 ->register();
Pattern matching:
1Rules::create('search_query')
2 ->when()
3 ->request_param('s', '*product*', 'LIKE') // Contains "product"
4 ->then()->custom('enhance_product_search')
5 ->register();
request_param checks both GET and POST parameters, with POST taking precedence if the same parameter exists in both.cookie#
Check for cookie existence or value.
Namespace: MilliRulesPackagesPHPConditionsCookie
Signature:
1->cookie($cookie_name, $value = null, $operator = '=')
Parameters:
$cookie_name(string): Cookie name$value(mixed): Expected value (null to check existence)$operator(string): Comparison operator (default:'=')
Supported Operators: All operators
Context Data Used: $context['request']['cookies'][$cookie_name] (from $_COOKIE)
Examples
Check cookie existence:
1Rules::create('has_session')
2 ->when()
3 ->cookie('session_id') // Cookie exists
4 ->then()->custom('load_session')
5 ->register();
Check cookie value:
1Rules::create('theme_preference')
2 ->when()
3 ->cookie('theme', 'dark')
4 ->then()->custom('apply_dark_theme')
5 ->register();
Cookie doesn't exist:
1Rules::create('first_time_visitor')
2 ->when()
3 ->cookie('visited_before', null, 'NOT EXISTS')
4 ->then()->custom('show_welcome_message')
5 ->register();
Multiple cookie values:
1Rules::create('preferred_languages')
2 ->when()
3 ->cookie('lang', ['en', 'en-US', 'en-GB'], 'IN')
4 ->then()->custom('use_english')
5 ->register();
Pattern matching cookies:
1Rules::create('tracking_cookies')
2 ->when()
3 ->cookie('_ga', 'GA*', 'LIKE') // Google Analytics cookie
4 ->then()->custom('record_analytics')
5 ->register();
constant#
Check PHP or WordPress constants.
Namespace: MilliRulesPackagesPHPConditionsConstant
Signature:
1->constant($constant_name, $value = null, $operator = '=')
Parameters:
$constant_name(string): Constant name$value(mixed): Expected value (null to check existence)$operator(string): Comparison operator (default:'=')
Supported Operators: All operators
Context Data Used: Uses defined() and constant() PHP functions
Examples
Check constant existence:
1Rules::create('has_debug_constant')
2 ->when()
3 ->constant('WP_DEBUG') // Constant is defined
4 ->then()->custom('enable_debug_mode')
5 ->register();
Check boolean constants:
1Rules::create('debug_enabled')
2 ->when()
3 ->constant('WP_DEBUG', true) // Debug is ON
4 ->then()->custom('show_debug_info')
5 ->register();
6
7Rules::create('debug_disabled')
8 ->when()
9 ->constant('WP_DEBUG', false) // Debug is OFF
10 ->then()->custom('hide_debug_info')
11 ->register();
Check string constants:
1Rules::create('local_environment')
2 ->when()
3 ->constant('WP_ENVIRONMENT_TYPE', 'local')
4 ->then()->custom('enable_local_features')
5 ->register();
Multiple environment types:
1Rules::create('non_production')
2 ->when()
3 ->constant('WP_ENVIRONMENT_TYPE', ['local', 'development'], 'IN')
4 ->then()->custom('enable_dev_tools')
5 ->register();
Version checking:
1Rules::create('php_version_check')
2 ->when()
3 ->constant('PHP_VERSION', '8.0', '>=')
4 ->then()->custom('use_php8_features')
5 ->register();
WordPress Package Conditions#
WordPress package conditions are available only when WordPress is detected. They provide access to WordPress-specific functionality and query information.
Generic WordPress is_* Conditions#
MilliRules supports any WordPress conditional tag function through the IsConditional class. Any function starting with is_ (like is_singular(), is_home(), is_archive(), is_category(), etc.) can be used as a condition.
How It Works:
- The
IsConditionalclass acts as a bridge between MilliRules and WordPress conditional tags - Supports all WordPress conditional tags: WordPress Conditional Tags
- Arguments passed to the condition are forwarded to the WordPress function
- Operates in two modes: Boolean Mode (no arguments) or Function Call Mode (with arguments)
Basic Usage (Boolean Mode)
When used without arguments, is_* conditions behave as simple boolean checks:
1// Fluent builder
2Rules::create('rule-1')
3 ->when()->is_404()->then()->register();
4
5// Array configuration
6[
7 'id' => 'rule-1',
8 'conditions' => [
9 [ 'type' => 'is_404' ], // is_404() IS TRUE
10 ],
11 'actions' => [],
12];
In this mode:
- The underlying WordPress function is called with no arguments
- The boolean result is compared to the configured
value(default:true) using the configuredoperator(default:IS)
Examples:
->is_404()→is_404() IS true->is_user_logged_in(false)→is_user_logged_in() IS false
Basic conditionals:
1// Check if any archive page
2Rules::create('archive_pages')
3 ->when()
4 ->is_archive()
5 ->then()->custom('show_archive_sidebar')
6 ->register();
Function Call Mode (With Arguments)
For conditionals that accept arguments, you can pass them directly to the builder. IsConditional will call the underlying is_* function with those arguments and compare the result to true.
In this mode:
- All non-boolean arguments are treated as function arguments for the underlying
is_*function - The condition always checks whether the function result is
true(usingvalue = trueinternally)
With arguments:
1// Single-argument conditional
2->is_singular('page') // is_singular('page') IS TRUE
3
4// Multi-argument conditional
5->is_tax('genre', 'sci-fi') // is_tax('genre', 'sci-fi') IS TRUE
Combining conditions:
1// Check if user is logged in and viewing a product archive
2Rules::create('archive_list_user_orders')
3 ->when()
4 ->is_user_logged_in()
5 ->is_post_type_archive('product')
6 ->then()->custom('show_orders')
7 ->register();
Using Operators with WordPress Conditionals
You can optionally pass a comparison operator as the last argument when using function call mode. This operator controls how the boolean result of the is_* function is compared to true.
Supported operators:
=!=ISIS NOT
1// Calls is_tax('genre', 'sci-fi') and compares result != TRUE
2// Check for multiple taxonomy terms with IN operator
3Rules::create('action_or_drama')
4 ->when()
5 ->is_tax('genre', 'sci-fi', '!=');
6 ->then()->custom('show_newsletter_cta')
7 ->register();
8
9// Check for multiple taxonomy terms with IN operator
10Rules::create('action_or_drama')
11 ->when()
12 ->is_tax('genre', ['action', 'drama'], 'IN')
13 ->then()->custom('show_intense_content_warning')
14 ->register();
Implementation Notes
- The builder records all raw method arguments in a generic
argskey in the condition config - The WordPress
IsConditionalclass interpretsargsto determine whether to operate in boolean mode or function-call mode - Other packages can reuse the
argsconvention in their own condition classes without any changes to core engine or base condition logic
Generic WordPress has_* Conditions#
MilliRules supports any WordPress conditional tag function starting with has_ through the HasConditional class. Functions like has_post_thumbnail(), has_block(), has_term(), has_excerpt(), etc. can all be used as conditions.
How It Works:
- The
HasConditionalclass acts as a bridge between MilliRules and WordPresshas_*conditional functions - Arguments passed to the condition are forwarded to the WordPress function
- Operates in two modes: Boolean Mode (no arguments) or Function Call Mode (with arguments)
Basic Usage (Boolean Mode)
When used without arguments, has_* conditions behave as simple boolean checks:
1// Fluent builder
2Rules::create('rule-1')
3 ->when()->has_post_thumbnail()->then()->register();
4
5// Array configuration
6[
7 'id' => 'rule-1',
8 'conditions' => [
9 [ 'type' => 'has_post_thumbnail' ], // has_post_thumbnail() IS TRUE
10 ],
11 'actions' => [],
12];
In this mode:
- The underlying WordPress function is called with no arguments
- The boolean result is compared to the configured
value(default:true) using the configuredoperator(default:IS)
Examples:
->has_post_thumbnail()→has_post_thumbnail() IS true->has_post_thumbnail(false)→has_post_thumbnail() IS false
Basic conditionals:
1// Check if the post has an excerpt
2Rules::create('has_excerpt')
3 ->when()
4 ->has_excerpt()
5 ->then()->custom('show_custom_excerpt')
6 ->register();
Function Call Mode (With Arguments)
For conditionals that accept arguments, you can pass them directly to the builder. HasConditional will call the underlying has_* function with those arguments and compare the result to true.
In this mode:
- All non-boolean arguments are treated as function arguments for the underlying
has_*function - The condition always checks whether the function result is
true(usingvalue = trueinternally)
With arguments:
1// Single-argument conditional
2->has_block('core/paragraph') // has_block('core/paragraph') IS TRUE
3
4// Multi-argument conditional
5->has_term('news', 'category') // has_term('news', 'category') IS TRUE
Combining conditions:
1// Check if a post has a featured image and a specific block
2Rules::create('rich_content')
3 ->when()
4 ->has_post_thumbnail()
5 ->has_block('core/gallery')
6 ->then()->custom('show_rich_layout')
7 ->register();
Using Operators with WordPress has_* Conditionals
You can optionally pass a comparison operator as the last argument when using function call mode. This operator controls how the boolean result of the has_* function is compared to true.
Supported operators:
=!=ISIS NOT
1// Check that a post does NOT have a specific term
2Rules::create('not_in_news')
3 ->when()
4 ->has_term('news', 'category', '!=')
5 ->then()->custom('show_generic_sidebar')
6 ->register();
7
8// Check that a post does NOT have a featured image
9Rules::create('no_thumbnail')
10 ->when()
11 ->has_post_thumbnail(false)
12 ->then()->custom('show_placeholder_image')
13 ->register();
Implementation Notes
- The builder records all raw method arguments in a generic
argskey in the condition config - The WordPress
HasConditionalclass interpretsargsto determine whether to operate in boolean mode or function-call mode - Other packages can reuse the
argsconvention in their own condition classes without any changes to core engine or base condition logic
post_type#
Check the current post type.
Namespace: MilliRulesPackagesWordPressConditionsPostType
Signature:
1->post_type($post_types, $operator = '=')
Parameters:
$post_types(string|array): Post type(s) to check$operator(string): Comparison operator (default:'=')
Supported Operators: =, !=, IN, NOT IN, EXISTS
Context Data Used: $context['wp']['post']['post_type']
Examples
Single post type:
1Rules::create('product_pages')
2 ->when()
3 ->post_type('product')
4 ->then()->custom('show_product_gallery')
5 ->register();
Multiple post types:
1Rules::create('content_types')
2 ->when()
3 ->post_type(['post', 'page', 'article'], 'IN')
4 ->then()->custom('enable_reading_time')
5 ->register();
Exclude post type:
1Rules::create('non_page_content')
2 ->when()
3 ->post_type('page', '!=')
4 ->then()->custom('show_author_bio')
5 ->register();
post_status#
Check the current post status.
Namespace: MilliRulesPackagesWordPressConditionsPostStatus
Signature:
1->post_status($status, $operator = '=')
Parameters:
$status(string|array): Post status(es) to check (publish,draft,pending,private,future,trash, etc.)$operator(string): Comparison operator (default:'=')
Supported Operators: =, !=, IN, NOT IN
How it resolves: Reads post_status from the queried object or global $post.
Examples
Single status:
1Rules::create('published_only')
2 ->when()
3 ->post_status('publish')
4 ->then()->custom('show_share_buttons')
5 ->register();
Multiple statuses:
1Rules::create('visible_content')
2 ->when()
3 ->post_status(['publish', 'private'], 'IN')
4 ->then()->custom('enable_comments')
5 ->register();
Exclude status:
1Rules::create('not_draft')
2 ->when()
3 ->post_status('draft', '!=')
4 ->then()->custom('index_content')
5 ->register();
post_status property — there is no WordPress is_post_status() conditional tag, which is why this dedicated condition exists.post_parent#
Check the parent post ID of the current post.
Namespace: MilliRulesPackagesWordPressConditionsPostParent
Signature:
1->post_parent($parent_id, $operator = '=')
Parameters:
$parent_id(int|array): Parent post ID(s) to check$operator(string): Comparison operator (default:'=')
Supported Operators: =, !=, IN, NOT IN, >, <
How it resolves: Reads post_parent from the queried object or global $post. Returns 0 if no post is found.
Examples
Exact parent:
1Rules::create('child_of_about')
2 ->when()
3 ->post_parent(10)
4 ->then()->custom('show_about_subnav')
5 ->register();
Has any parent (hierarchical post):
1Rules::create('is_child_page')
2 ->when()
3 ->post_parent(0, '>')
4 ->then()->custom('show_breadcrumbs')
5 ->register();
Is top-level page (no parent):
1Rules::create('top_level_page')
2 ->when()
3 ->post_parent(0)
4 ->then()->custom('show_child_pages_menu')
5 ->register();
->post_parent(0, '>') as an efficient way to check if a page is a child of any parent, regardless of which parent.user_role#
Check the roles of the current logged-in user.
Namespace: MilliRulesPackagesWordPressConditionsUserRole
Signature:
1->user_role($role, $operator = 'IN')
Parameters:
$role(string|array): Role(s) to check (administrator,editor,author,contributor,subscriber, or custom roles)$operator(string): Comparison operator (default:'IN')
Supported Operators: =, !=, IN, NOT IN
How it resolves: Loads user data from context and checks the roles array. Uses intersection logic — a user with multiple roles matches if any of their roles match any of the expected roles.
Examples
Single role:
1Rules::create('admin_features')
2 ->when()
3 ->user_role('administrator')
4 ->then()->custom('show_admin_toolbar')
5 ->register();
Multiple roles:
1Rules::create('editorial_features')
2 ->when()
3 ->user_role(['editor', 'administrator'], 'IN')
4 ->then()->custom('show_editorial_tools')
5 ->register();
Exclude role:
1Rules::create('non_subscribers')
2 ->when()
3 ->user_role('subscriber', '!=')
4 ->then()->custom('show_premium_content')
5 ->register();
->user_role('editor') will match a user who has both editor and administrator roles.wp_environment#
Check the WordPress environment type.
Namespace: MilliRulesPackagesWordPressConditionsWpEnvironment
Signature:
1->wp_environment($environment, $operator = '=')
Parameters:
$environment(string|array): Environment type(s) to check (production,staging,development,local)$operator(string): Comparison operator (default:'=')
Supported Operators: =, !=, IN, NOT IN
How it resolves: Uses wp_get_environment_type() (WordPress 5.5+). Falls back to 'production' if the function is unavailable.
Examples
Production check:
1Rules::create('production_only')
2 ->when()
3 ->wp_environment('production')
4 ->then()->custom('enable_caching')
5 ->register();
Non-production environments:
1Rules::create('dev_tools')
2 ->when()
3 ->wp_environment(['development', 'local'], 'IN')
4 ->then()->custom('enable_debug_bar')
5 ->register();
Exclude production:
1Rules::create('not_production')
2 ->when()
3 ->wp_environment('production', '!=')
4 ->then()->custom('show_environment_banner')
5 ->register();
->constant('WP_ENVIRONMENT_TYPE', 'local') from the PHP package for the same effect. The wp_environment condition is a convenience wrapper that handles the function availability check.query_var#
Check WordPress query variables.
Namespace: MilliRulesPackagesWordPressConditionsQueryVar
Signature:
1->query_var($name, $value = null, $operator = '=')
Parameters:
$name(string): Query variable name (e.g.,paged,post_type,s,m,author, etc.)$value(mixed): Expected value (null defaults toEXISTSoperator)$operator(string): Comparison operator (default:'=', or'EXISTS'when no value)
Supported Operators: =, !=, IN, NOT IN, LIKE, EXISTS, NOT EXISTS
How it resolves: First checks the execution context, then falls back to get_query_var(). When no value is provided, automatically uses the EXISTS operator.
Examples
Check existence:
1Rules::create('is_search')
2 ->when()
3 ->query_var('s') // Defaults to EXISTS
4 ->then()->custom('enhance_search')
5 ->register();
Check value:
1Rules::create('page_two')
2 ->when()
3 ->query_var('paged', 2)
4 ->then()->custom('show_pagination_notice')
5 ->register();
Check post type query var:
1Rules::create('product_archive_query')
2 ->when()
3 ->query_var('post_type', 'product')
4 ->then()->custom('show_product_filters')
5 ->register();
Check non-existence:
1Rules::create('no_search')
2 ->when()
3 ->query_var('s', null, 'NOT EXISTS')
4 ->then()->custom('show_default_content')
5 ->register();
query_var is a name-based condition — the first argument is always the query variable name, not a value. This makes it unique among WordPress conditions.Combining Conditions#
PHP Conditions Only#
1Rules::create('api_authentication', 'php')
2 ->when()
3 ->request_url('/api/*')
4 ->request_method('POST')
5 ->request_header('Authorization', 'Bearer *', 'LIKE')
6 ->cookie('session_id')
7 ->then()->custom('process_api_request')
8 ->register();
WordPress Conditions Only#
1Rules::create('admin_users_posts', 'wp')
2 ->when()
3 ->is_user_logged_in()
4 ->is_singular('post')
5 ->post_type('post')
6 ->then()->custom('show_admin_tools')
7 ->register();
Mixed PHP and WordPress Conditions#
1Rules::create('secure_admin_area', 'wp')
2 ->when()
3 ->request_url('/wp-admin/*') // PHP condition
4 ->is_user_logged_in() // WordPress condition
5 ->cookie('admin_preference') // PHP condition
6 ->then()->custom('customize_admin')
7 ->register();
'wp' when WordPress conditions are used.Condition Evaluation Order#
Conditions are evaluated in the order they're defined:
1Rules::create('sequential_checks')
2 ->when()
3 ->request_url('/api/*') // Checked first
4 ->request_method('POST') // Checked second
5 ->cookie('auth_token') // Checked third
6 ->then()->custom('action')
7 ->register();
For performance, place the most restrictive or fastest conditions first:
1// ✅ Good - quick checks first
2Rules::create('optimized')
3 ->when()
4 ->request_method('POST') // Fast check
5 ->request_url('/specific/path') // Fast check
6 ->custom('complex_validation') // Slow custom check last
7 ->then()->custom('action')
8 ->register();
9
10// ❌ Bad - slow check first
11Rules::create('unoptimized')
12 ->when()
13 ->custom('complex_validation') // Slow check first!
14 ->request_method('POST')
15 ->request_url('/specific/path')
16 ->then()->custom('action')
17 ->register();
Custom Conditions#
When built-in conditions aren't sufficient, create custom conditions:
1// Register custom condition
2Rules::register_condition('is_weekend', function(Context $context) {
3 return date('N') >= 6; // Saturday or Sunday
4});
5
6// Use in rule
7Rules::create('weekend_special')
8 ->when()
9 ->custom('is_weekend')
10 ->request_url('/shop/*')
11 ->then()->custom('apply_weekend_discount')
12 ->register();
See Creating Custom Conditions for detailed information.
Best Practices#
1. Use Specific Conditions#
1// ✅ Good - specific conditions
2->when()
3 ->request_url('/api/users')
4 ->request_method('GET')
5
6// ❌ Bad - too broad
7->when()
8 ->request_url('*')
2. Leverage Auto-Detection#
1// ✅ Good - let MilliRules detect operators
2->request_url('/admin/*') // LIKE auto-detected
3->request_method(['GET', 'HEAD']) // IN auto-detected
4->constant('WP_DEBUG', true) // IS auto-detected
5
6// ❌ Unnecessary - explicit when auto-detected works
7->request_url('/admin/*', 'LIKE')
8->request_method(['GET', 'HEAD'], 'IN')
9->constant('WP_DEBUG', true, 'IS')
3. Group Related Conditions#
1// ✅ Good - logical grouping
2Rules::create('api_security')
3 ->when()
4 // API context
5 ->request_url('/api/*')
6 ->request_method('POST')
7
8 // Authentication
9 ->cookie('session_id')
10 ->request_header('Authorization')
11 ->then()->custom('process_secure_api')
12 ->register();
4. Use Comments for Complex Logic#
1Rules::create('complex_caching')
2 ->when()
3 // Cacheable request types
4 ->request_method(['GET', 'HEAD'], 'IN')
5
6 // Not in admin or login areas
7 ->request_url('/wp-admin/*', 'NOT LIKE')
8 ->request_url('/wp-login.php', '!=')
9
10 // User hasn't disabled caching
11 ->cookie('disable_cache', null, 'NOT EXISTS')
12 ->then()->custom('apply_cache')
13 ->register();
Next Steps#
- Built-in Actions - Learn about available actions
- Operators - Master comparison and pattern matching
- Custom Conditions - Create your own conditions
- Examples - See conditions in real-world scenarios
Need more details? Check the API Reference for complete method signatures and parameters.