📁 File Manager Pro
v10.0.3 | PHP: 8.1.34
Server: LiteSpeed
2026-06-29 01:06:17
📂
/ (Root)
/
home
/
apkbfjox
/
2jbet.net.pk
/
wp-content
/
plugins
/
generateblocks-pro
/
includes
/
conditions
📍 /home/apkbfjox/2jbet.net.pk/wp-content/plugins/generateblocks-pro/includes/conditions
🔄 Refresh
✏️
Editing: class-condition-abstract.php
Writable
<?php /** * Abstract Condition Base Class. * * @package GenerateBlocks */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Abstract base class for conditions. */ abstract class GenerateBlocks_Pro_Condition_Abstract implements GenerateBlocks_Pro_Condition_Interface { /** * Get default rule metadata. * * @return array */ protected function get_default_rule_metadata() { return [ 'needs_value' => true, 'value_type' => 'text', ]; } /** * Parse custom field value structure with edge case handling. * * @param string $value The value to parse. * @return array */ protected function parse_custom_value( $value ) { // Handle null, empty, or non-string values. if ( null === $value || '' === $value ) { return [ 'field_name' => '', 'comparison_value' => '', ]; } // Convert to string if not already (handles numbers, booleans). if ( ! is_string( $value ) ) { if ( is_scalar( $value ) ) { $value = (string) $value; } else { // Arrays, objects, resources - return empty. return [ 'field_name' => '', 'comparison_value' => '', ]; } } // Handle extremely long values to prevent memory issues. if ( 10000 < strlen( $value ) ) { $value = substr( $value, 0, 10000 ); } if ( false === strpos( $value, '|' ) ) { return [ 'field_name' => sanitize_text_field( $value ), 'comparison_value' => '', ]; } $parts = explode( '|', $value, 2 ); return [ 'field_name' => sanitize_text_field( $parts[0] ), 'comparison_value' => sanitize_text_field( $parts[1] ?? '' ), ]; } /** * Sanitize custom field value with comprehensive validation. * * @param mixed $value The value to sanitize. * @return string */ protected function sanitize_custom_value( $value ) { if ( null === $value || '' === $value ) { return ''; } // Handle arrays or objects - reject them for custom fields. if ( ! is_scalar( $value ) ) { return ''; } $value = (string) $value; // Prevent extremely long values. if ( 10000 < strlen( $value ) ) { $value = substr( $value, 0, 10000 ); } if ( false !== strpos( $value, '|' ) ) { $parts = $this->parse_custom_value( $value ); // Validate field name (basic WordPress meta key validation). $field_name = $parts['field_name']; if ( empty( $field_name ) || 255 < strlen( $field_name ) ) { return ''; } // Only rebuild if we have a valid field name. return $field_name . '|' . $parts['comparison_value']; } return sanitize_text_field( $value ); } /** * Standardized meta field parsing with edge case handling. * * @param string $rule The condition rule. * @param mixed $value The condition value. * @return array Parsed field data with 'field_name' and 'comparison_value'. */ protected function parse_meta_field( $rule, $value ) { if ( 'custom' === $rule ) { return $this->parse_custom_value( $value ); } // Ensure rule is a valid string. if ( ! is_string( $rule ) || empty( $rule ) ) { return [ 'field_name' => '', 'comparison_value' => '', ]; } // Handle non-scalar values. if ( ! is_scalar( $value ) && null !== $value ) { $comparison_value = ''; } else { $comparison_value = is_scalar( $value ) ? sanitize_text_field( $value ) : ''; } return [ 'field_name' => sanitize_text_field( $rule ), 'comparison_value' => $comparison_value, ]; } /** * Enhanced meta existence evaluation with comprehensive validation. * * @param string $meta_type The meta type ('post', 'user', 'option'). * @param int $object_id The object ID (post ID, user ID, etc.). * @param string $meta_key The meta key to check. * @param string $operator The operator ('exists' or 'not_exists'). * @return bool */ protected function evaluate_meta_existence( $meta_type, $object_id, $meta_key, $operator ) { // Validate meta type. if ( ! in_array( $meta_type, [ 'post', 'user', 'option' ], true ) ) { return false; } // Validate meta key. if ( empty( $meta_key ) || ! is_string( $meta_key ) || 255 < strlen( $meta_key ) ) { return false; } // Validate object ID for non-option types. if ( 'option' !== $meta_type ) { if ( ! is_numeric( $object_id ) || 1 > $object_id || PHP_INT_MAX < $object_id ) { return false; } $object_id = absint( $object_id ); } // Validate operator. if ( ! in_array( $operator, [ 'exists', 'not_exists' ], true ) ) { return false; } try { if ( 'option' === $meta_type ) { $exists = false !== get_option( $meta_key, false ); } else { $exists = metadata_exists( $meta_type, $object_id, $meta_key ); } } catch ( Exception $e ) { // Database errors, invalid meta types, etc. return false; } return 'not_exists' === $operator ? ! $exists : $exists; } /** * Enhanced meta value retrieval with comprehensive validation. * * @param string $meta_type The meta type ('post', 'user', 'option'). * @param int $object_id The object ID (post ID, user ID, etc.). * @param string $meta_key The meta key. * @param string $operator The condition operator. * @param mixed $comparison_value The value to compare against. * @return bool */ protected function evaluate_meta_value( $meta_type, $object_id, $meta_key, $operator, $comparison_value ) { // Validate inputs using same validation as existence check. if ( ! in_array( $meta_type, [ 'post', 'user', 'option' ], true ) ) { return false; } if ( empty( $meta_key ) || ! is_string( $meta_key ) || 255 < strlen( $meta_key ) ) { return false; } if ( 'option' !== $meta_type ) { if ( ! is_numeric( $object_id ) || 1 > $object_id || PHP_INT_MAX < $object_id ) { return false; } $object_id = absint( $object_id ); } // Handle multi-value operators first. if ( $this->is_multi_value_operator( $operator ) ) { try { if ( 'option' === $meta_type ) { $meta_value = get_option( $meta_key ); } elseif ( 'post' === $meta_type ) { $meta_value = get_post_meta( $object_id, $meta_key, true ); } elseif ( 'user' === $meta_type ) { $meta_value = get_user_meta( $object_id, $meta_key, true ); } else { return false; } } catch ( Exception $e ) { return false; } return $this->evaluate_multi_value_meta( $operator, $meta_value, $comparison_value ); } // Get single meta value with error handling. try { if ( 'option' === $meta_type ) { $meta_value = get_option( $meta_key ); } elseif ( 'post' === $meta_type ) { $meta_value = get_post_meta( $object_id, $meta_key, true ); } elseif ( 'user' === $meta_type ) { $meta_value = get_user_meta( $object_id, $meta_key, true ); } else { return false; } } catch ( Exception $e ) { return false; } // Evaluate based on operator. switch ( $operator ) { case 'equals': return $this->compare_values_equals( $meta_value, $comparison_value ); case 'contains': return is_string( $meta_value ) && is_string( $comparison_value ) && false !== strpos( $meta_value, $comparison_value ); case 'not_contains': return ! is_string( $meta_value ) || ! is_string( $comparison_value ) || false === strpos( $meta_value, $comparison_value ); case 'greater_than': return $this->compare_numeric( $meta_value, $comparison_value, '>' ); case 'less_than': return $this->compare_numeric( $meta_value, $comparison_value, '<' ); default: return false; } } /** * Check if operator supports multiple values. * * @param string $operator The operator to check. * @return bool */ protected function is_multi_value_operator( $operator ) { $multi_operators = [ 'includes_any', 'includes_all', 'excludes_any', 'excludes_all' ]; return in_array( $operator, $multi_operators, true ); } /** * Parse value as array for multi-select operators with comprehensive validation. * * @param mixed $value The value to parse. * @return array */ protected function parse_multi_value( $value ) { if ( is_array( $value ) ) { // Limit array size to prevent memory issues. if ( 1000 < count( $value ) ) { $value = array_slice( $value, 0, 1000 ); } return array_filter( array_map( 'sanitize_text_field', $value ) ); } if ( null === $value || '' === $value ) { return []; } // Handle non-scalar values. if ( ! is_scalar( $value ) ) { return []; } $value = (string) $value; // Prevent extremely long JSON strings. if ( 50000 < strlen( $value ) ) { return []; } // Try to decode as JSON first. if ( '{' === $value[0] || '[' === $value[0] ) { $decoded = json_decode( $value, true ); if ( is_array( $decoded ) ) { // Limit decoded array size. if ( 1000 < count( $decoded ) ) { $decoded = array_slice( $decoded, 0, 1000 ); } return array_filter( array_map( 'sanitize_text_field', $decoded ) ); } } // Fallback to single value. return [ sanitize_text_field( $value ) ]; } /** * Generic multi-value condition evaluator with validation. * * @param string $operator The operator (includes_any, includes_all, etc.). * @param mixed $condition_values The condition values (array or string). * @param callable $match_callback Callback function to check if a value matches. * @return bool */ protected function evaluate_multi_value_generic( $operator, $condition_values, $match_callback ) { if ( ! is_callable( $match_callback ) ) { return false; } if ( ! in_array( $operator, [ 'includes_any', 'includes_all', 'excludes_any', 'excludes_all' ], true ) ) { return false; } $values = $this->parse_multi_value( $condition_values ); if ( empty( $values ) ) { return false; } $matches = []; foreach ( $values as $value ) { try { $matches[] = call_user_func( $match_callback, $value ); } catch ( Exception $e ) { $matches[] = false; } } // Apply operator logic. switch ( $operator ) { case 'includes_any': return in_array( true, $matches, true ); case 'includes_all': return ! in_array( false, $matches, true ); case 'excludes_any': return ! in_array( true, $matches, true ); case 'excludes_all': return in_array( false, $matches, true ); default: return false; } } /** * Evaluate multi-value condition. * * @param string $operator The operator (includes_any, includes_all, etc.). * @param mixed $target_value The current value to check against. * @param mixed $condition_values The condition values (array or string). * @return bool */ protected function evaluate_multi_value( $operator, $target_value, $condition_values ) { return $this->evaluate_multi_value_generic( $operator, $condition_values, function( $value ) use ( $target_value ) { return $this->values_match( $target_value, $value ); } ); } /** * Evaluate multi-value condition for arrays (like post terms). * * @param string $operator The operator (includes_any, includes_all, etc.). * @param array $target_values Array of current values to check against. * @param mixed $condition_values The condition values (array or string). * @return bool */ protected function evaluate_multi_value_array( $operator, $target_values, $condition_values ) { if ( ! is_array( $target_values ) ) { return false; } return $this->evaluate_multi_value_generic( $operator, $condition_values, function( $value ) use ( $target_values ) { foreach ( $target_values as $target_value ) { if ( $this->values_match( $target_value, $value ) ) { return true; } } return false; } ); } /** * Enhanced multi-value meta evaluation with error handling. * * @param string $operator The operator (includes_any, includes_all, etc.). * @param mixed $meta_value The meta value (could be string, array, or object). * @param mixed $condition_values The condition values (array or string). * @return bool */ protected function evaluate_multi_value_meta( $operator, $meta_value, $condition_values ) { // Convert meta value to array if it's not already. $meta_values = []; if ( is_array( $meta_value ) ) { // Limit meta array size. if ( 1000 < count( $meta_value ) ) { $meta_value = array_slice( $meta_value, 0, 1000 ); } $meta_values = array_map( 'sanitize_text_field', $meta_value ); } elseif ( null !== $meta_value && '' !== $meta_value ) { if ( is_scalar( $meta_value ) ) { $meta_value_string = (string) $meta_value; // Try to decode JSON if it looks like JSON. if ( ( '{' === $meta_value_string[0] || '[' === $meta_value_string[0] ) && 50000 > strlen( $meta_value_string ) ) { $decoded = json_decode( $meta_value_string, true ); if ( is_array( $decoded ) ) { if ( 1000 < count( $decoded ) ) { $decoded = array_slice( $decoded, 0, 1000 ); } $meta_values = array_map( 'sanitize_text_field', $decoded ); } else { $meta_values = [ sanitize_text_field( $meta_value_string ) ]; } } else { $meta_values = [ sanitize_text_field( $meta_value_string ) ]; } } } return $this->evaluate_multi_value_generic( $operator, $condition_values, function( $condition_value ) use ( $meta_values ) { foreach ( $meta_values as $current_meta_value ) { if ( $this->values_match( $current_meta_value, $condition_value ) ) { return true; } } return false; } ); } /** * Check if two values match (with loose comparison). * * @param mixed $value1 First value. * @param mixed $value2 Second value. * @return bool */ protected function values_match( $value1, $value2 ) { // Convert both to strings for comparison. return (string) $value1 === (string) $value2; } /** * Compare values with type juggling for equals operator. * * @param mixed $value1 First value. * @param mixed $value2 Second value. * @return bool */ protected function compare_values_equals( $value1, $value2 ) { return $value1 == $value2; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison } /** * Compare numeric values with enhanced validation. * * @param mixed $value1 First value. * @param mixed $value2 Second value. * @param string $operator Comparison operator (>, <). * @return bool */ protected function compare_numeric( $value1, $value2, $operator ) { if ( ! in_array( $operator, [ '>', '<' ], true ) ) { return false; } // Handle edge cases for numeric comparison. if ( null === $value1 || null === $value2 ) { return false; } if ( ! is_numeric( $value1 ) || ! is_numeric( $value2 ) ) { return false; } // Check for potential overflow issues. if ( ! is_finite( (float) $value1 ) || ! is_finite( (float) $value2 ) ) { return false; } $float1 = floatval( $value1 ); $float2 = floatval( $value2 ); if ( '>' === $operator ) { return $float1 > $float2; } elseif ( '<' === $operator ) { return $float1 < $float2; } return false; } /** * Enhanced value sanitization with better validation. * * @param mixed $value The value to sanitize. * @param string $rule The rule being used. * @return mixed */ public function sanitize_value( $value, $rule ) { if ( 'custom' === $rule ) { return $this->sanitize_custom_value( $value ); } // Handle array values for multi-select. if ( is_array( $value ) ) { if ( 1000 < count( $value ) ) { $value = array_slice( $value, 0, 1000 ); } return array_filter( array_map( 'sanitize_text_field', $value ) ); } return sanitize_text_field( $value ); } /** * Enhanced query parameter validation. * * @param string $param Parameter name. * @return mixed */ protected function get_query_param( $param ) { if ( empty( $param ) || ! is_string( $param ) || 255 < strlen( $param ) ) { return null; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! isset( $_GET[ $param ] ) ) { return null; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $value = wp_unslash( $_GET[ $param ] ); // Handle arrays in query params. if ( is_array( $value ) ) { if ( 100 < count( $value ) ) { $value = array_slice( $value, 0, 100 ); } return array_map( 'sanitize_text_field', $value ); } // Prevent extremely long query values. if ( is_string( $value ) && 10000 < strlen( $value ) ) { $value = substr( $value, 0, 10000 ); } return sanitize_text_field( $value ); } /** * Enhanced input validation for server variables. * * @param string $var Variable name. * @return string */ protected function get_server_var( $var ) { if ( empty( $var ) || ! is_string( $var ) || 100 < strlen( $var ) ) { return ''; } // Whitelist allowed server variables for security. $allowed_vars = [ 'HTTP_USER_AGENT', 'HTTP_REFERER', 'REQUEST_METHOD', 'REMOTE_ADDR', 'HTTP_HOST', 'REQUEST_URI', 'QUERY_STRING', ]; if ( ! in_array( $var, $allowed_vars, true ) ) { return ''; } if ( ! isset( $_SERVER[ $var ] ) ) { return ''; } $value = wp_unslash( $_SERVER[ $var ] ); // Type-specific validation for enhanced security. switch ( $var ) { case 'HTTP_REFERER': // Validate and sanitize as URL. $value = esc_url_raw( $value ); break; case 'HTTP_USER_AGENT': // Remove control characters and normalize. $value = preg_replace( '/[\x00-\x1F\x7F]/', '', $value ); $value = sanitize_text_field( $value ); break; default: $value = sanitize_text_field( $value ); } // Prevent extremely long values. if ( is_string( $value ) && 10000 < strlen( $value ) ) { $value = substr( $value, 0, 10000 ); } return $value; } /** * Enhanced cookie validation. * * @param string $cookie_name Cookie name. * @return string|null */ protected function get_cookie_value( $cookie_name ) { if ( empty( $cookie_name ) || ! is_string( $cookie_name ) || 255 < strlen( $cookie_name ) ) { return null; } // Basic cookie name validation (prevent obvious XSS attempts). // Also reject browser-reserved cookie prefixes (__Host-, __Secure-). if ( ! preg_match( '/^[a-zA-Z0-9_-]+$/', $cookie_name ) || 0 === strpos( $cookie_name, '__' ) ) { return null; } if ( ! isset( $_COOKIE[ $cookie_name ] ) ) { return null; } $value = wp_unslash( $_COOKIE[ $cookie_name ] ); // Prevent extremely long cookie values. if ( is_string( $value ) && 4096 < strlen( $value ) ) { $value = substr( $value, 0, 4096 ); } return sanitize_text_field( $value ); } /** * Check if cookie exists with validation. * * @param string $cookie_name Cookie name. * @return bool */ protected function cookie_exists( $cookie_name ) { if ( empty( $cookie_name ) || ! is_string( $cookie_name ) || 255 < strlen( $cookie_name ) ) { return false; } // Reject browser-reserved cookie prefixes. if ( ! preg_match( '/^[a-zA-Z0-9_-]+$/', $cookie_name ) || 0 === strpos( $cookie_name, '__' ) ) { return false; } return isset( $_COOKIE[ $cookie_name ] ); } /** * Check if query parameter exists with validation. * * @param string $param_name Parameter name. * @return bool */ protected function query_param_exists( $param_name ) { if ( empty( $param_name ) || ! is_string( $param_name ) || 255 < strlen( $param_name ) ) { return false; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended return isset( $_GET[ $param_name ] ); } /** * Enhanced meta value check - determines if meta has a non-empty value. * * @param string $meta_type The meta type ('post', 'user', 'option'). * @param int $object_id The object ID (post ID, user ID, etc.). * @param string $meta_key The meta key. * @return bool */ protected function evaluate_meta_has_value( $meta_type, $object_id, $meta_key ) { // Validate inputs using same validation as existence check. if ( ! in_array( $meta_type, [ 'post', 'user', 'option' ], true ) ) { return false; } if ( empty( $meta_key ) || ! is_string( $meta_key ) || 255 < strlen( $meta_key ) ) { return false; } if ( 'option' !== $meta_type ) { if ( ! is_numeric( $object_id ) || 1 > $object_id || PHP_INT_MAX < $object_id ) { return false; } $object_id = absint( $object_id ); } // Get the value. try { if ( 'option' === $meta_type ) { // For options, false means it doesn't exist. if ( false === get_option( $meta_key, false ) ) { return false; } $value = get_option( $meta_key ); } elseif ( 'post' === $meta_type ) { // First check if it exists. if ( ! metadata_exists( $meta_type, $object_id, $meta_key ) ) { return false; } $value = get_post_meta( $object_id, $meta_key, true ); } elseif ( 'user' === $meta_type ) { // First check if it exists. if ( ! metadata_exists( $meta_type, $object_id, $meta_key ) ) { return false; } $value = get_user_meta( $object_id, $meta_key, true ); } else { return false; } } catch ( Exception $e ) { return false; } // Check for various "empty" states. if ( null === $value || '' === $value || false === $value ) { return false; } // Empty array is also "no value". if ( is_array( $value ) && 0 === count( $value ) ) { return false; } // Everything else is considered "has value" (including 0 and "0"). return true; } /** * Check if cookie has a non-empty value. * * @param string $cookie_name Cookie name. * @return bool */ protected function cookie_has_value( $cookie_name ) { if ( ! $this->cookie_exists( $cookie_name ) ) { return false; } $value = $this->get_cookie_value( $cookie_name ); // Check for various "empty" states. if ( null === $value || '' === $value || false === $value ) { return false; } // Everything else is considered "has value" (including 0 and "0"). return true; } /** * Check if query parameter has a non-empty value. * * @param string $param_name Parameter name. * @return bool */ protected function query_param_has_value( $param_name ) { if ( ! $this->query_param_exists( $param_name ) ) { return false; } $value = $this->get_query_param( $param_name ); // Check for various "empty" states. if ( null === $value || '' === $value || false === $value ) { return false; } // Empty array is also "no value". if ( is_array( $value ) && 0 === count( $value ) ) { return false; } // Everything else is considered "has value" (including 0 and "0"). return true; } /** * Check if referrer has a non-empty value. * * @return bool */ protected function referrer_has_value() { $referrer = $this->get_server_var( 'HTTP_REFERER' ); // Check for various "empty" states. if ( null === $referrer || '' === $referrer || false === $referrer ) { return false; } // Everything else is considered "has value". return true; } /** * Check if operator needs a value. * * @param string $operator The operator. * @return bool */ protected function operator_needs_value( $operator ) { $no_value_operators = [ 'exists', 'not_exists', 'has_value', 'no_value' ]; return ! in_array( $operator, $no_value_operators, true ); } /** * Check if a rule actually supports multi-value selection. * * @param string $rule The rule key. * @return bool */ protected function rule_supports_multi_select( $rule ) { $metadata = $this->get_rule_metadata( $rule ); // Only support multi-select if we have object selectors. $multi_select_types = [ 'object_selector', 'hierarchical_object_selector' ]; return in_array( $metadata['value_type'] ?? '', $multi_select_types, true ); } /** * Get operators with intelligent filtering based on actual multi-select support. * * @param string $rule The rule key. * @return array Array of operator keys. */ public function get_operators_for_rule( $rule ) { // Get base operators for this condition type. $types = GenerateBlocks_Pro_Conditions::get_condition_types(); $class_name = get_class( $this ); $base_operators = []; foreach ( $types as $type_data ) { if ( $type_data['class'] === $class_name ) { $base_operators = $type_data['operators']; break; } } // If this rule doesn't support multi-select, remove ALL "any/all" operators. if ( ! $this->rule_supports_multi_select( $rule ) ) { $multi_operators = [ 'includes_any', 'includes_all', 'excludes_any', 'excludes_all' ]; $base_operators = array_diff( $base_operators, $multi_operators ); } return $base_operators; } }
💾 Save Changes
❌ Cancel