PHP Classes

File: src/Filters/QueryMatchFilter.php

Recommend this page to a friend!
  Classes of Sascha Greuel   PHP JSON Path   src/Filters/QueryMatchFilter.php   Download  
File: src/Filters/QueryMatchFilter.php
Role: Class source
Content type: text/plain
Description: Class source
Class: PHP JSON Path
Query values from data structures like XPATH
Author: By
Last change: [BUG-69] fixed in clause filter

+ added trim to explode to support both 1,2,3 and 1, 2, 3 inputs
+ dropped in_array strict equality check to be in line with the other
standard equality checks such as (== and !=)
Date: 3 years ago
Size: 4,560 bytes
 

Contents

Class file image Download
<?php

/**
 * JSONPath implementation for PHP.
 *
 * @license https://github.com/SoftCreatR/JSONPath/blob/main/LICENSE MIT License
 */

declare(strict_types=1);

namespace
Flow\JSONPath\Filters;

use
Flow\JSONPath\AccessHelper;
use
RuntimeException;

use function
explode;
use function
in_array;
use function
is_array;
use function
is_string;
use function
preg_match;
use function
preg_replace;
use function
strpos;
use function
strtolower;
use function
substr;

class
QueryMatchFilter extends AbstractFilter
{
    protected const
MATCH_QUERY_OPERATORS = '
      @(\.(?<key>[^\s<>!=]+)|\[["\']?(?<keySquare>.*?)["\']?\])
      (\s*(?<operator>==|=~|=|<>|!==|!=|>=|<=|>|<|in|!in|nin)\s*(?<comparisonValue>.+))?
    '
;

   
/**
     * @inheritDoc
     */
   
public function filter($collection): array
    {
       
preg_match('/^' . static::MATCH_QUERY_OPERATORS . '$/x', $this->token->value, $matches);

        if (!isset(
$matches[1])) {
            throw new
RuntimeException('Malformed filter query');
        }

       
$key = $matches['key'] ?: $matches['keySquare'];

        if (
$key === '') {
            throw new
RuntimeException('Malformed filter query: key was not set');
        }

       
$operator = $matches['operator'] ?? null;
       
$comparisonValue = $matches['comparisonValue'] ?? null;

        if (
is_string($comparisonValue)) {
            if (
strpos($comparisonValue, "[") === 0 && substr($comparisonValue, -1) === "]") {
               
$comparisonValue = substr($comparisonValue, 1, -1);
               
$comparisonValue = preg_replace('/^[\'"]/', '', $comparisonValue);
               
$comparisonValue = preg_replace('/[\'"]$/', '', $comparisonValue);
               
$comparisonValue = preg_replace('/[\'"],[ ]*[\'"]/', ',', $comparisonValue);
               
$comparisonValue = array_map('trim', explode(",", $comparisonValue));
            } else {
               
$comparisonValue = preg_replace('/^[\'"]/', '', $comparisonValue);
               
$comparisonValue = preg_replace('/[\'"]$/', '', $comparisonValue);

                if (
strtolower($comparisonValue) === 'false') {
                   
$comparisonValue = false;
                } elseif (
strtolower($comparisonValue) === 'true') {
                   
$comparisonValue = true;
                } elseif (
strtolower($comparisonValue) === 'null') {
                   
$comparisonValue = null;
                }
            }
        }

       
$return = [];

        foreach (
$collection as $value) {
            if (
AccessHelper::keyExists($value, $key, $this->magicIsAllowed)) {
               
$value1 = AccessHelper::getValue($value, $key, $this->magicIsAllowed);

                if (
$operator === null && $value1) {
                   
$return[] = $value;
                }

               
/** @noinspection TypeUnsafeComparisonInspection */
                // phpcs:ignore -- This is a loose comparison by design.
               
if (($operator === '=' || $operator === '==') && $value1 == $comparisonValue) {
                   
$return[] = $value;
                }

               
/** @noinspection TypeUnsafeComparisonInspection */
                // phpcs:ignore -- This is a loose comparison by design.
               
if (($operator === '!=' || $operator === '!==' || $operator === '<>') && $value1 != $comparisonValue) {
                   
$return[] = $value;
                }

                if (
$operator === '=~' && @preg_match($comparisonValue, $value1)) {
                   
$return[] = $value;
                }

                if (
$operator === '>' && $value1 > $comparisonValue) {
                   
$return[] = $value;
                }

                if (
$operator === '>=' && $value1 >= $comparisonValue) {
                   
$return[] = $value;
                }

                if (
$operator === '<' && $value1 < $comparisonValue) {
                   
$return[] = $value;
                }

                if (
$operator === '<=' && $value1 <= $comparisonValue) {
                   
$return[] = $value;
                }

                if (
$operator === 'in' && is_array($comparisonValue) && in_array($value1, $comparisonValue)) {
                   
$return[] = $value;
                }

                if (
                    (
$operator === 'nin' || $operator === '!in') &&
                   
is_array($comparisonValue) &&
                    !
in_array($value1, $comparisonValue)
                ) {
                   
$return[] = $value;
                }
            }
        }

        return
$return;
    }
}