'object', 'properties' => array( 'key' => array( 'type' => 'string' ), 'value' => array( 'type' => 'string' ), ), ); } /** * Gets the default value for a newly created condition of this type. * * @return mixed */ public function default_value() { return array( 'key' => '', 'value' => '', ); } /** * Evaluates the condition against the given context. * * @param Context $context Request context value object. * @param string $operator Operator identifier. * @param mixed $value Configured value. * @return bool */ public function evaluate( Context $context, string $operator, $value ): bool { $key = is_array( $value ) && isset( $value['key'] ) && is_scalar( $value['key'] ) ? (string) $value['key'] : ''; if ( '' === $key ) { return true; // Invalid — fail open. } $params = $context->query_params; // PHP stores `?utm.source=` / `?utm source=` as `utm_source`; look the key up the same way. if ( ! array_key_exists( $key, $params ) ) { $key = str_replace( array( ' ', '.' ), '_', ltrim( $key ) ); } $has = array_key_exists( $key, $params ); if ( 'exists' === $operator ) { return $has; } if ( 'not_exists' === $operator ) { return ! $has; } // A non-empty key above implies $value is an array. $expected = isset( $value['value'] ) && is_scalar( $value['value'] ) ? (string) $value['value'] : ''; /* * Request values are sanitised with sanitize_text_field() (see * ContextFactory); compare like with like so `avalue_matches( $params[ $key ], $expected ); return 'is_not' === $operator ? ! $match : $match; } /** * Compares a query-parameter value against the expected string. * * Array parameters (`?tag[]=a&tag[]=b`) match when any member matches, so a * repeated parameter never gets stringified into "Array". * * @param mixed $actual Raw parameter value from the request. * @param string $expected Expected value. * @return bool */ private function value_matches( $actual, string $expected ): bool { if ( is_array( $actual ) ) { foreach ( $actual as $item ) { if ( $this->value_matches( $item, $expected ) ) { return true; } } return false; } if ( is_scalar( $actual ) || null === $actual ) { return (string) $actual === $expected; } return false; } }