arraypress / wp-compare-utils
Comprehensive comparison utilities for WordPress development with meta value support
dev-main
2025-07-21 18:26 UTC
Requires
- php: >=7.4
This package is auto-updated.
Last update: 2025-09-02 11:28:27 UTC
README
Comprehensive comparison utilities for WordPress development with special support for meta value comparisons and conditional logic. Handles operator decoding, multiple data types, and complex comparison scenarios.
Features
- 🎯 Multiple Data Types: Boolean, numeric, string, date, time, array, IP address comparisons
- 🔧 WordPress-Optimized: Handles meta value operator encoding issues
- ⚡ Flexible Operators: Support for equality, contains, starts/ends with, ranges, and more
- 🛡️ Robust Validation: Built-in validation for all comparison types
- 📊 Multi-Value Support: Compare against arrays of values with AND/OR logic
- 🌐 IP Address Support: CIDR range matching and IP validation
- 🕒 Time Comparisons: Perfect for store hours, scheduling, and time-based logic
Requirements
- PHP 7.4 or later
- WordPress 5.0 or later
Installation
composer require arraypress/wp-compare-utils
Basic Usage
Boolean Comparisons
use ArrayPress\CompareUtils\Compare; // Meta value boolean checks $is_featured = Compare::boolean( '==', true, $post_meta_featured ); $not_draft = Compare::boolean( '!=', false, $post_published ); // Supported operators: ==, ===, is, equal_to, !=, !==, is_not, not_equal_to
Numeric Comparisons
// Price comparisons with float precision $in_budget = Compare::numeric( '<=', 100.00, $product_price ); $adult = Compare::numeric( '>=', 18, $user_age ); $exact_match = Compare::numeric( '==', 99.99, $price, 0.01 ); // Custom epsilon // Supported operators: ==, ===, !=, !==, >, >=, <, <=
String Comparisons
// Case-sensitive comparisons $has_keyword = Compare::string( 'contains', 'wordpress', $post_content ); $is_admin = Compare::string( 'starts_with', 'admin', $page_slug ); $is_php = Compare::string( 'ends_with', '.php', $filename ); // Case-insensitive comparisons $matches = Compare::string_i( '==', 'WORDPRESS', $platform ); // true for 'wordpress' // Supported operators: ==, !=, contains, not_contains, starts_with, ends_with
Date and Time Comparisons
// Date comparisons $is_future = Compare::dates( '>', 'now', $event_date ); $this_year = Compare::dates( '>=', '2024-01-01', $post_date ); // Time comparisons (perfect for store hours) $is_open = Compare::times( '>=', '09:00', $current_time ); $before_close = Compare::times( '<', '17:00', $current_time ); // Store hours example $current_time = date( 'H:i' ); $store_open = Compare::times( '>=', '09:00', $current_time ); $store_close = Compare::times( '<=', '17:00', $current_time ); $is_open = $store_open && $store_close;
Array Comparisons
// Check if value exists in array $has_role = Compare::array( 'contains', 'administrator', $user_roles ); $not_in_list = Compare::array( 'not_contains', $user_id, $blocked_users ); // Multi-value comparisons (unified method) $tags = [ 'wordpress', 'php', 'development' ]; $content = 'This is about WordPress and PHP development'; // String subject - check if content contains any tags $relevant = Compare::multi( 'contains', $tags, $content ); // true // String subject - check if content contains ALL tags $comprehensive = Compare::multi( 'contains_all', $tags, $content ); // true // Array subject - check if arrays have any overlap $user_skills = [ 'php', 'javascript', 'css' ]; $has_skills = Compare::multi( 'contains', $tags, $user_skills ); // true (php match)
IP Address Comparisons
// Exact IP matching $is_admin_ip = Compare::ip_address( '==', '192.168.1.100', $user_ip ); // CIDR range matching $internal = Compare::ip_address( '==', '192.168.1.0/24', $user_ip ); $not_blocked = Compare::ip_address( '!=', '10.0.0.0/8', $user_ip );
Advanced Examples
// WordPress meta field filtering $posts = get_posts( [ 'meta_query' => [ [ 'key' => 'price', 'value' => 100, 'compare' => 'NUMERIC' ] ] ] ); // Use Compare utils for additional filtering $affordable_posts = array_filter( $posts, function ( $post ) { $price = get_post_meta( $post->ID, 'price', true ); return Compare::numeric( '<=', 50, $price ); } ); // Multi-condition filtering $premium_posts = array_filter( $posts, function ( $post ) { $featured = get_post_meta( $post->ID, 'featured', true ); $category = get_post_meta( $post->ID, 'category', true ); $tags = get_post_meta( $post->ID, 'tags', true ); return Compare::boolean( '==', true, $featured ) && Compare::array( 'contains', 'premium', explode( ',', $category ) ) && Compare::multi( 'contains', [ 'exclusive', 'vip' ], $tags ); } );
API Reference
Core Comparison Methods
Method | Description | Returns |
---|---|---|
boolean($operator, $value, $bool) |
Compare boolean values | bool |
numeric($operator, $value1, $value2, $epsilon) |
Compare numbers with precision | bool |
string($operator, $value, $string) |
Compare strings (case-sensitive) | bool |
string_i($operator, $value, $string) |
Compare strings (case-insensitive) | bool |
dates($operator, $value, $date) |
Compare date values | bool |
times($operator, $value, $time) |
Compare time values (H:i format) | bool |
array($operator, $value, $array) |
Check if value exists in array | bool |
Multi-Value Methods
Method | Description | Returns |
---|---|---|
multi($operator, $values, $subject) |
Compare multiple values against string or array | bool |
Specialized Methods
Method | Description | Returns |
---|---|---|
ip_address($operator, $value, $ip) |
Compare IP addresses (supports CIDR) | bool |
fuzzy_string($value, $string, $max_distance) |
Fuzzy string matching with Levenshtein | bool |
Supported Operators
Equality Operators
==
,===
,equal_to
!=
,!==
,not_equal_to
Comparison Operators
>
,>=
,<
,<=
String Operators
contains
,not_contains
starts_with
,ends_with
Multi-Value Operators
contains
- Any value matchescontains_all
- All values must matchnot_contains
- No values match
Boolean Operators
is
,is_not
Common Use Cases
WordPress Post Filtering
// Filter posts by custom fields function filter_posts_by_criteria( $posts, $criteria ) { return array_filter( $posts, function ( $post ) use ( $criteria ) { $price = get_post_meta( $post->ID, 'price', true ); $featured = get_post_meta( $post->ID, 'featured', true ); $category = get_post_meta( $post->ID, 'category', true ); return Compare::numeric( '<=', $criteria['max_price'], $price ) && Compare::boolean( '==', $criteria['featured'], $featured ) && Compare::string( '==', $criteria['category'], $category ); } ); }
User Access Control
// Check user permissions and conditions function can_user_access( $user_id, $resource ) { $user = get_user_by( 'id', $user_id ); $user_roles = $user->roles; $user_ip = $_SERVER['REMOTE_ADDR']; $blocked_ips = get_option( 'blocked_ip_ranges', [] ); $has_permission = Compare::multi( 'contains', [ 'administrator', 'editor' ], $user_roles ); $ip_allowed = ! Compare::multi( 'contains', $blocked_ips, $user_ip ); return $has_permission && $ip_allowed; }
Store Hours / Business Logic
// Check if store is currently open function is_store_open() { $current_time = date( 'H:i' ); $current_day = date( 'N' ); // 1 (Monday) to 7 (Sunday) $hours = get_option( 'store_hours', [ '1' => [ 'open' => '09:00', 'close' => '17:00' ], // Monday '2' => [ 'open' => '09:00', 'close' => '17:00' ], // Tuesday // ... etc ] ); if ( ! isset( $hours[ $current_day ] ) ) { return false; // Closed on this day } $today_hours = $hours[ $current_day ]; $after_open = Compare::times( '>=', $today_hours['open'], $current_time ); $before_close = Compare::times( '<=', $today_hours['close'], $current_time ); return $after_open && $before_close; }
Content Personalization
// Show content based on user criteria function should_show_promotion( $user_id ) { $user_meta = get_user_meta( $user_id ); $purchase_history = get_user_meta( $user_id, 'purchase_history', true ); $user_tags = get_user_meta( $user_id, 'tags', true ); // Multiple conditions $is_premium = Compare::boolean( '==', true, $user_meta['premium'][0] ?? false ); $recent_purchase = Compare::dates( '>', '-30 days', $user_meta['last_purchase'][0] ?? '' ); $target_audience = Compare::multi( 'contains', [ 'vip', 'loyal' ], explode( ',', $user_tags ) ); return $is_premium || $recent_purchase || $target_audience; }
API Response Filtering
// Filter API responses based on criteria function filter_api_results( $results, $filters ) { return array_filter( $results, function ( $item ) use ( $filters ) { $matches = true; foreach ( $filters as $field => $criteria ) { $operator = $criteria['operator']; $value = $criteria['value']; if ( ! isset( $item[ $field ] ) ) { $matches = false; break; } switch ( $criteria['type'] ) { case 'string': $matches = Compare::string( $operator, $value, $item[ $field ] ); break; case 'numeric': $matches = Compare::numeric( $operator, $value, $item[ $field ] ); break; case 'array': $matches = Compare::array( $operator, $value, $item[ $field ] ); break; } if ( ! $matches ) { break; } } return $matches; } ); }
Meta Value Support
This library was specifically designed to handle WordPress meta value comparisons, including the operator decoding issue where operators saved as meta values can contain hidden characters:
// Automatically handles encoded operators from meta values $operator = get_post_meta( $post_id, 'comparison_operator', true ); // Might be encoded $threshold = get_post_meta( $post_id, 'threshold', true ); $current_value = get_post_meta( $post_id, 'current_value', true ); // The comparison will work even if operator has encoding issues $passes = Compare::numeric( $operator, $threshold, $current_value );
Key Benefits
- WordPress-Native: Built specifically for WordPress development patterns
- Meta Value Safe: Handles operator encoding issues automatically
- Type Flexible: Works with various data types and WordPress meta formats
- Performance Focused: Efficient comparisons suitable for filtering large datasets
- Developer Friendly: Intuitive method names and consistent API
- Self-Contained: No external dependencies beyond PHP core functions
Requirements
- PHP 7.4+
- WordPress 5.0+
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the GPL-2.0-or-later License.